March 9, 2021
Hot Topics:

Building WML Gadgets: A Calendar

  • By Steve Schafer
  • Send Email »
  • More Articles »
Next and Previous Month Navigation

Adding next and previous month navigation is fairly straightforward. We simply determine what the next/previous month and year would be and use an appropriate <GO> tag with encoded name/value pairs.

Note: We determine the month and year up front to eliminate the need to do any processing later on (moving from Dec to Jan, or from Jan back to Dec).

The function Add_Delta_Days from the Date::Calc module allows us to do date math, adding days to a known date. Adding 31 to the first day of any month will give us a date in the following month, while subtracting 1 from the first day of any month will give us a date in the prior month. Such code resembles the following:

# Set next month/year
($nextyear,$nextmonth,$nextday) =

# Set prev month/year
($prevyear,$prevmonth,$prevday) =

We then use the variables when outputting the <GO> tags, similar to this:

<do type="accept" label="Back" name="Prev">
  <go href="cal.pl?month=$prevmonth&amp;year=$prevyear" />

The Finished Script

When we put it all together, the script is as follows:

Listing of cal.pl

#!/usr/bin/perl  -w

# Define modules
use CGI qw(:standard);
use Date::Calc ':all';

# Parse command line or name/value pairs
# Command line:
if (@ARGV) { 
  $month = (shift @ARGV);
  $year = (shift @ARGV);

} else {

  # Name/value pairs
  if ($ENV{REQUEST_METHOD} eq 'GET') {
    foreach $input (split("&",$ENV{QUERY_STRING})) {
      if ($input =~ /(.*)=(.*)/) {
        ($key,$value) = ($1, $2);
        # Add keyword/value pair to a list
        $inputs{$key} = $value;
        $month = $inputs{month};
        $year = $inputs{year};


# If we don't have a valid date from params,
#   set date to today (server clock)
if (!check_date($year,$month,1)) {
  ($year,$month,$day) = Today([$gmt]);

# Find weekday (Sun - Sat) of first of the month
$firstdow = Day_of_Week($year,$month,"1");
# Convert Sun (7) to 0
if ("$firstdow" == "7") { $firstdow = 0; }

# Month text
$monthtext = Month_to_Text($month);

# Set next month/year
($nextyear,$nextmonth,$nextday) =

# Set prev month/year
($prevyear,$prevmonth,$prevday) =

# Pass WML header
print header(-type=>'text/vnd.wap.wml');

# Print WML header and beginning tags
print <<ENDHEADER;
<?xml version="1.0"?>

<do type="accept" label="Back" name="Prev">
  <go href="cal.pl?month=$prevmonth&amp;year=$prevyear" />
<do type="option" label="Fwd" name="Next">
  <go href="cal.pl?month=$nextmonth&amp;year=$nextyear" />
$monthtext $year<br/>
<table columns="7">
<tr><td> S </td><td> M </td><td> T </td><td> W </td>
<td> T </td><td> F </td><td> S </td></tr>


# Start first date row
print "<tr>";

# Print blank cells up to first day
$x = 0;
while ($x < $firstdow) {
  print "<td>&nbsp;</td>";

# Start with first day
$day = 1;

# Work through month from first day through last
while ($day <= Days_in_Month($year,$month)) {
  print "<td>";
  if ($day < 10) { print "&nbsp;"; }
  print $day."|</td>";
  # At end of week, close row
  if ($x == 7) { 
    print "</tr>\n";
    # If we aren't done, start new row
    if ($day != Days_in_Month($year,$month)) {
      print "<tr>";
    $x = 0

# Fill out last row (if applicable)
#   with blank cells
if ($x ne 0) {
  while ($x <= 6) {
    print "<td>&nbsp;</td>";
  print "</tr>";

# Close tags, card, and WML
print <<ENDFOOTER;


If a mobile browser without parameters calls the script, it will display the current month along with two buttons to move forward and backward by month, respectively. Alternatively, the script can be accessed with encoded name/value pairs to specify which month to display. For example, the following URL results in the display shown in the figure:



Room for Improvement

As with previous projects, several things could be added to improve our calendar:

  • Better labels for our navigation keys-the first three letters of the month (e.g., "Dec"), for example, instead of "Back" and "Fwd"
  • Marking the current date, perhaps with underlining.
  • A navigation control to allow the user to specify a particular month to display
  • A navigation control to display the current month

What Do You Want from WML?

I'm interested in hearing what you need/want to do with WML. I'll use some of the more challenging or common ideas in upcoming articles. Send your ideas to the address below.

About the Author

Steve Schafer is the chief operating officer of Progeny Linux Systems, a Linux-based consulting company in Indianapolis, Indiana. He has written several technical books and articles and can be reached at sschafer@synergy-tech.com.

# # #

Page 5 of 5

This article was originally published on December 21, 2002

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date