The Month Array

Why present the current date as 8/31/2013 when you can express it as August 31, 2013? Because some things are easy to program and some are easy for the program’s user to read.

Take the current date. It’s a rather simple process to obtain the current date (and time) in C. Well, it may not be simple: I’m guessing that most programmers just copy the same code over and over, so that process is simple enough.

The following listing shows a sample “show me the date” type of program. It first uses the time() function to fetch the current Unix Epoch tick count. That value, tictoc in the code, is then fed to the localtime() function, which fills a tm structure with details about the current tick count, i.e., the right now time.

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

int main()
{
    time_t tictoc;
    struct tm *today;

    time(&tictoc);          /* Get the current time */
    today = localtime(&tictoc);
                            /* Read today structure */
    printf("Today is %d/%d/%d\n",
        today->tm_mon+1,
        today->tm_mday,
        today->tm_year+1900);
    return(0);
}

The three key members in the tm structure, referenced by the variable today in the code above, are tm_mon, tm_mday, and tm_year.

The tm_mon member represents the current month. Its values range from 0 through 11, not the 1 through 12 you would expect. Therefore, the printf() statement adds one to the value at Line 13.

The tm_mday member represents the current day of the month, ranging from 1 through 31. Of course, the top value is limited based on the current month.

The tm_year member represents the current year, minus 1900. That 1900 is added to the value at Line 15. (If you wanted to display the year as a two-digit value, you’d subtract 100. I suppose the original purpose of the tm_year member was to display a two-digit year, which works fine for the 20th Century, but not for the 21st.)

Here’s the sample output:

Today is 8/31/2013

And, of course, if you’re in a locale where the day comes before the month, just swap the variables at Lines 13 and 14 in the code:

Today is 31/8/2013

To display the month as a text string, such as “August” instead of 8, you need to add an array of month strings. Such an addition is shown in the the following modification to the original code:

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

int main()
{
    time_t tictoc;
    struct tm *today;
    char *months[12] = {
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December" };

    time(&tictoc);          /* Get the current time */
    today = localtime(&tictoc);
                            /* Read today structure */
    printf("Today is %s %d, %d\n",
        months[today->tm_mon],
        today->tm_mday,
        today->tm_year+1900);
    return(0);
}

I’ve changed only two items between the first and second code listings.

First is the addition of the string array at Line 8. The char *months[12] declaration tells the compiler that 12 strings are being created. Each string is then specified on its own line. The compiler calculates the string’s lengths and all that. This type of declaration is simpler than doing char months[12][10], which would be another way to express such an allocation.

Second, the printf() statement has been modified. The %s conversion character is used to display the month string. The tm_mon member is used, but it doesn’t need to be incremented by 1; in the months array, element 0 is “January,” so everything works out fine. I’ve also changed the format so that the output looks like this:

Today is August 31, 2013.

The point to all this is that it’s not really that difficult to switch from an all digit representation of the current day to a more readable, human representation. All you need to do is add an array of strings representing the months, then use the fact that the tm structure references months starting at 0 to help the code fetch the proper month string from that array.

If you’re willing to play with this concept further, know that the tm_wday member of the tm structure contains the current day of the week, where 0 represents Sunday.

Leave a Reply