C
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Arrays and Strings
-
Section 5: Pointers
-
Section 6: Memory Management
-
Section 7: Structures and Unions
-
Section 8: The Preprocessor and Build Process
-
Section 9: Standard Library: stdio.h
-
Section 10: Standard Library: stdlib.h
-
Section 11: Standard Library: string.h
-
Section 12: Standard Library: ctype.h and wctype.h
-
Section 13: Standard Library: math.h, complex.h, fenv.h, tgmath.h
-
Section 14: Standard Library: Type and Limit Headers
-
Section 15: Standard Library: Error Handling and Debugging
-
Section 16: Standard Library: Localization and Encoding
-
Section 17: Standard Library: time.h
-
Section 18: Standard Library: Concurrency (C11)
-
Section 19: POSIX and System Programming (unistd.h)
-
Section 20: More Data Structures
-
Section 21: Algorithms in C
-
Section 22: Bitwise Operations
-
Section 23: Command-Line Programs
-
Section 24: Debugging and Best Practices
-
Section 25: Compiler and Language Internals
-
Section 26: Embedded and Cross-Platform Considerations
-
Section 27: Networking Basics
-
Section 28: Practical Projects
-
Section 29: Interview Practice
-
Section 30: C23 Modern Features
-
Section 31: More Practice and Review
134: Calendar Time Calculations
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()andlocaltime()to get the current date. - Use the
tm_wdayfield of thestruct 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.
There are no comments for now.