The Month Program, Phase I

Unix features a handy command line tool called cal. When typed by its lonesome, cal spits up a text calendar on the terminal window. Or you can follow cal with a month and year value to see a specific month, or just the year value to see a year’s calendar. It’s nifty!

Here’s the output of the cal command for this month, January 2014:

    January 2014
Su Mo Tu We Th Fr Sa
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

I use this command in my always-open terminal window as a quick way to check dates. It’s much faster than slugging my way through a GUI calendar or scheduling app. It’s even faster than flying in the Dashboard in OS X.

But I want more!

Specifically, I want the monthly calendar output to highlight the current day of the month.

Ideally, it would look like this:

    January 2014
Su Mo Tu We Th Fr Sa
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Such text coloring is possible by programming the terminal directly, using ANSI codes, or using the NCurses library. Rather than muddy the waters, I’d settle for this type of output:

    January 2014
Su Mo Tu We Th Fr Sa
          1  2  3[ 4]
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Above, I’m using square brackets to enclose the current day. That keeps with the text-only type of output C does, plus it’s a bit easier to code.

Of course, it’s only easier when you can generate the current month in the first place. To do so, you have to really start by determining which day of the week is the first day of the current month. For that task, you need to use your standard C library toolbox and the localtime() function.

The localtime() function (prototyped in the time.h header) fills a tm structure with information about a given Unix Epoch time value, also known as a time_t value. Normally the value of time_t reflects the current date and time, which is fetched by using the time() function. You can also backfill that structure to fetch information about any specific date, which was demonstrated in a previous Lesson.

As a reference, here is the information found in the typical tm structure:

int tm_sec;     /* seconds (0 - 60) */
int tm_min;     /* minutes (0 - 59) */
int tm_hour;    /* hours (0 - 23) */
int tm_mday;    /* day of month (1 - 31) */
int tm_mon;     /* month of year (0 - 11) */
int tm_year;    /* year - 1900 */
int tm_wday;    /* day of week (Sunday = 0) */
int tm_yday;    /* day of year (0 - 365) */
int tm_isdst;   /* is summer time in effect? */
char *tm_zone;  /* abbreviation of timezone name */
long tm_gmtoff; /* offset from UTC in seconds */

Some library implementations add more members, but what you see above is pretty common.

The sample code below uses the tm structure to display three relevant tidbits of information: The current day of the week, the current month, and the current day of the month.

#include <stdio.h>
#include <time.h>

int main()
{
    time_t tictoc;
    struct tm *rightnow;
    int wday,monthday,month;
    char *months[12] = {
        "January", "February", "March", "April",
        "May", "June", "July", "August",
        "September", "October", "November", "December" };
    char *weekdays[7] = {
        "Sunday", "Monday", "Tuesday", "Wednesday",
        "Thursday", "Friday", "Saturday" };

    time(&tictoc);                  /* get Unix epoch time */
                                    /* fill tm struct rightnow */
    rightnow = localtime(&tictoc);
                                    /* Get info from struct */
    wday = rightnow->tm_wday;       /* 0=Sunday */
    monthday = rightnow->tm_mday;   /* 1 to 31 */
    month = rightnow->tm_mon;       /* 0=January */

    printf("Today is %s %s %d\n",
        weekdays[wday],
        months[month],
        monthday);

    return(0);
}

Sample output from this code depends on the current date. Here’s what I see:

Today is Saturday January 4

Once the program knows the current day of the month, the next step is to concoct an algorithm to determine on which day of the week the first would fall. You have all the information to do it on your own, or you can wait a week and continue with the next Lesson.

Leave a Reply