Skip to Content
Course content

134: Calendar Time Calculations

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Handling time in C can feel like a bit of a minefield. Between the epoch, leap years, and those quirky offsets in the struct tm, it's very easy to end up off by a day or—worse—calculating a date in the year 3924. I've been there.

To get a handle on this, let's build something practical: a "Countdown to New Year" utility. We want to find out exactly how many days are left until January 1st of the next year, based on whatever the system clock says right now.

Grabbing the current moment

First, we need the current time. In C, we usually start with time_t, which is basically just a big integer representing seconds since January 1, 1970. But seconds are useless for calendar calculations; we need something we can actually read, like years and months. That's where localtime() comes in.

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

int main() {
    time_t now = time(NULL); 
    struct tm *current_time = localtime(&now);

    printf("Today is %d-%02d-%02d\n", 
            current_time->tm_year + 1900, 
            current_time->tm_mon + 1, 
            current_time->tm_mday);
    return 0;
}

Notice I added 1900 to the year and 1 to the month. That's a quirk of struct tm that bites everyone eventually. I'll get to that in a second.

Setting our target date

Now we need to define when New Year's Day actually happens. I'll create a new struct tm and manually set the fields for January 1st of next year. Since current_time already tells us the current year, we'll just increment that.

struct tm target_date = *current_time; // Copy current time settings
target_date.tm_mon = 0; // January
target_date.tm_mday = 1;
target_date.tm_hour = 0;
target_date.tm_min = 0;
target_date.tm_sec = 0;
target_date.tm_year++; // Move to next year

The "Year 1900" trap

Here is where I almost messed up this example. When I first wrote this logic a few years back, I tried to initialize the target date by simply writing target_date.tm_year = 2025;. When I ran the code, the program told me there were over 200,000 days until New Year's.

Why? Because tm_year isn't the actual year—it's the number of years since 1900. By setting it to 2025, I accidentally told C the date was the year 3925. Always remember: if you're assigning a year manually, you must subtract 1900. If you're reading a year, you must add 1900.

Turning dates back into seconds

We have the current time as a time_t and the target date as a struct tm. To find the difference, we need them both in the same format. mktime() is our best friend here; it takes a struct tm and converts it back into a time_t (seconds since the epoch).

Once we have both as seconds, we can use difftime() to get the gap, then divide by the number of seconds in a day (86,400).

time_t target_time = mktime(&target_date);
double seconds_diff = difftime(target_time, now);
int days_left = (int)(seconds_diff / (60 * 60 * 24));

printf("There are %d days left until New Year's!\n", days_left);

It's a straightforward process, but the magic happens in that conversion from a human-readable structure (tm) to a machine-readable number (time_t). That's the core of almost every calendar calculation you'll ever do in C.




📋 Practical Task

Build a "Days Since Last Monday" Calculator

Write a program that calculates how many days have passed since the most recent Monday.

  • Use time() and localtime() to get the current date.
  • Use the tm_wday field of the struct tm (where 0 is Sunday, 1 is Monday, etc.) to determine how many days ago the last Monday occurred.
  • If today is Monday, the result should be 0.
  • Output the result to the console in a friendly sentence.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.