Converting Month Strings to Integers

I saw this problem on stackoverflow: How can you take a month string and convert it into an integer value, one through 12? The student submitting the query used a long if-else if-else construction. I have a better idea.

The time functions in C use zero for January and 11 for December. But this assignment is to return values one through 12 for January through December. As the user on stackoverflow attempted, you could use a series of strcmp() statements in a complex if-else if-else structure, but I thought of a shortcut.

Here are the twelve months:

January
February
March
April
May
June
July
August
September
October
November
December

The month’s initial letters are J(3), F(1), M(2), A(2), S(1), O(1), and D(1).

For the months of February, September, October, and December, you need only check the month’s first letter.

For J months, you check the fourth letter: U is January, E is June, Y is July.

For M months, check the third letter: R is March, Y is May

For A months, check the second letter: P is April, U is August.

A function to return the the proper values can use a switch-case structure to process the month names, as shown in the following code:

2022_08_13-Lesson.c

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

int getMonthasInt(const char *monthString);

int main()
{
    const char *month[] = {
        "January", "February", "March", "April",
        "May", "June", "July", "August", "September",
        "October", "November", "December"
    };
    int count = 20;
    int r,m;

    /* seed the randomizer */
    srand( (unsigned)time(NULL) );

    /* process 20 random month names */
    while(count)
    {
        r = rand() % 12;
        m = getMonthasInt(month[r]);
        printf("%02d %s\n",m,month[r]);
        count--;
    }

    return(0);
}

int getMonthasInt(const char *monthString)
{
    switch( *(monthString) )
    {
        case 'J':
            switch( *(monthString+3) )
            {
                case 'u':
                    return(1);        /* JanUary */
                case 'e':
                    return(6);        /* JunE */
                case 'y':
                    return(7);        /* JulY */
            }
        case 'F':
            return(2);                /* February */
        case 'M':
            switch( *(monthString+2) )
            {
                case 'r':
                    return(3);        /* MaRch */
                case 'y':
                    return(5);        /* MaY */
            }
        case 'A':
            switch( *(monthString+1) )
            {
                case 'p':
                    return(4);        /* APril */
                case 'u':
                    return(8);        /* AUgust */
            }
        case 'S':
            return(9);                /* September */
        case 'O':
            return(10);                /* October */
        case 'N':
            return(11);                /* November */
        case 'D':
            return(12);                /* December */
    }
    return(-1);
}

In the main() function, a const array of strings (pointers) represents the months. The randomizer is seeded. Then a while loop spins 20 times, each time calling the getMonthasInt() function with a random month string. The function returns the month’s integer value, 1 through 12, which is output. All this action is setup for the getMonthasInt() function, the core of the problem.

The getMonthasInt() function uses nested switch-case constructions to sift through the names. I don’t check case, and no break or default statements are used as success is immediately processed as a return value. If by some chance execution falls through, the final return value of -1 is generated.

For an example, consider the nested switch-case for 'J': The fourth character in the string, *(monthString+3) is checked for 'u', 'e', and 'y'. This technique sifts through the names without doing a full strcmp() comparison. In fact, only the necessary parts of this complex structure are executed for any given month, as opposed to all the processing and churning that takes place if you use if-else statements and strcmp().

Here’s a sample run:

01 January
08 August
05 May
03 March
09 September
06 June
11 November
11 November
09 September
06 June
02 February
05 May
12 December
10 October
01 January
08 August
09 September
07 July
11 November
05 May

I suppose my insight into this approach stems from my proto-programmer days when processing muscle was weak and memory was limited. This type of sifting works given that the names are the same and capitalization is consistent. Even so, not much more coding is required to differentiate between letter cases. Regardless, it was a fun puzzle to solve.

3 thoughts on “Converting Month Strings to Integers

  1. If you do this

    int n = monthString[i][0] + monthString[i][1] + monthString[i][2];

    you get one of 12 unique ints which you can use in a switch with 12 cases to set the month number from 1 to 12. The numbers are:

    281
    269
    288
    291
    295
    301
    299
    285
    296
    294
    307
    268

    I know it’s a bit rubbish but it’s the best I could think of.

Leave a Reply