Creating a time_t Value

Ho boy! This time_t project turned out to be a lot more complex than I thought it would be!

The problem: Count the number of seconds elapsed from January 1, 1970 to a given year, month, and day. This task is easy for a computer, but not that easy to code if you want to get the value correct.

The number of seconds elapsed from January 1, 1970, the Unix Epoch, is stored in a time_t data type. This typedef is created in the time.h header file and used by various C library time functions.

Providing that you know the year, month, day, hour, minute, and second, you can perform the math necessary to calculate a time_t value. Because this value is the number of seconds elapsed from January 1, 1970, the math works this way for a given year, month, day, hour, minute, and seconds:

(Year - 1970) * month * day * hour * minute + seconds

The first issue to contend with is that zero values can mess up multiplication. For example, January is month zero. For dates in January, the calculation’s result is zero plus the seconds value, which is way off.

The second issue, which was the biggest issue for me, is how to deal with leap years? Each day is 86,400 seconds. Missing a few February 29ths over the years adds up quickly.

To best deal with both issues, I crafted the epoch() function. Specifically with regards to last week’s Lesson, I wanted only the time_t value that gives me the current day at midnight. Therefore the hour, minute, and second values are zero; the function deals with only the year, month, and day:

time_t epoch(int year, int mon, int day)

Rather than have code multiply each year by 365, I decided to count months instead: A loop would progress from 1970 through the year before the current one, with a nested loop accumulating days of the month. The days variable tracks the days in the month for each month within each year, the month[] array looks like this:

int month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

Here is the nested loop to count days in a year, including leap years:

    /* calculate the number of days */
    days = 0;
    for( y=1970; y<year; y++ )
    {
        for( m=0; m<12; m++ )
        {
            if( m==1 )        /* february */
                days += february(y);
            else
                days += month[m];
        }
    }

For the second month, if( m==1 ), the february() function is called. This function returns the values 28 or 29 based on the year. It’s inspired by an old Exercise challenge, with the solution available here.

After the years are tallied, another loop (not shown above) adds days from the months so far in the current year. Then finally, the day of the current month is added. This total, stored in int variable days, is multiplied by 24 * 60 * 60, or 86,400, to obtain what I hope is the proper time_t value.

Alas my code still had issues, which I get into in next week’s Lesson. Until then, you can click here to preview the code.

3 thoughts on “Creating a time_t Value

Leave a Reply