Definition
struct tm is a standard C structure defined in <time.h> that represents broken-down time components (year, month, day, hour, minute, second, etc.). It serves as the intermediate human-readable format for time manipulation, conversion, and formatting. Functions like localtime, gmtime, mktime, and strftime rely on this structure to translate between raw epoch timestamps (time_t) and calendar representations.
Structure Members
The C standard mandates the following fields. All are of type int.
| Member | Range / Meaning | Notes |
|---|---|---|
tm_sec | [0, 60] | Seconds (60 allows for leap seconds) |
tm_min | [0, 59] | Minutes |
tm_hour | [0, 23] | Hours (24-hour format) |
tm_mday | [1, 31] | Day of the month |
tm_mon | [0, 11] | 0-based months (0=January, 11=December) |
tm_year | Years since 1900 | Current year minus 1900 (e.g., 2024 → 124) |
tm_wday | [0, 6] | 0-based day of week (0=Sunday, 6=Saturday) |
tm_yday | [0, 365] | 0-based day of year (0=Jan 1) |
tm_isdst | -1, 0, or 1 | Daylight Saving Time flag: -1=unknown, 0=not in effect, 1=in effect |
Usage Examples
#include <stdio.h>
#include <time.h>
int main(void) {
time_t raw_time = time(NULL);
struct tm *time_info = localtime(&raw_time);
// Accessing components (remember offsets)
printf("Year: %d\n", time_info->tm_year + 1900);
printf("Month: %d\n", time_info->tm_mon + 1);
printf("Day: %d\n", time_info->tm_mday);
// Formatting with strftime
char buffer[64];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", time_info);
printf("Formatted: %s\n", buffer);
return 0;
}
Modifying Time & Normalization
struct tm event = {0};
event.tm_year = 2025 - 1900;
event.tm_mon = 13; // Invalid month (intentional)
event.tm_mday = 1;
// mktime normalizes out-of-range values and returns time_t
time_t epoch = mktime(&event); // Handles Jan 13 → Feb 13 automatically
event = *localtime(&epoch); // Re-read normalized components
printf("Normalized: %d-%02d-%02d\n",
event.tm_year + 1900, event.tm_mon + 1, event.tm_mday);
Rules & Constraints
- Static Buffer Warning:
localtime()andgmtime()return pointers to a static internal buffer. Subsequent calls overwrite previous results. Not thread-safe. - Normalization Behavior:
mktime()automatically adjusts out-of-range values (e.g.,tm_mon = 14becomes next year's March). It also recomputestm_wdayandtm_yday. - DST Handling:
mktime()usestm_isdstto determine DST. If set to-1, it attempts to detect DST automatically based on system timezone rules. - Epoch Dependency:
struct tmfields are calendar-based, not tied to a specific epoch until converted viamktime(). - C Standard Limitations: Does not store timezone offsets, nanosecond precision, or leap year rules explicitly. Relies on OS timezone database.
Best Practices
- Use reentrant functions: Prefer
localtime_r()andgmtime_r()(POSIX) orlocaltime_s()/gmtime_s()(C11 Annex K) for thread safety. - Zero-initialize before use:
struct tm t = {0};ensures undefined fields don't contain garbage. - Always normalize after modification: Call
mktime()immediately after manually settingtmfields to recalculate dependent fields and apply DST rules. - Use
strftimefor output: Avoid manual formatting.strftimehandles locale, padding, and timezone correctly. - Store
time_tfor persistence: Serializetime_t(or Unix timestamps) instead ofstruct tm. Timezone/DST rules change over time. - Validate ranges manually if strictness required:
mktimesilently normalizes. Check bounds before calling if out-of-range values indicate logic errors.
Common Pitfalls
- 🔴 Forgetting 1900 offset: Printing
tm_yeardirectly shows124instead of2024. Must add1900. - 🔴 Using 1-based months: Assigning
tm_mon = 12for December causesmktimeto normalize to January of next year. - 🔴 Ignoring static buffer overwrites: Storing
localtime()pointers and accessing them later yields corrupted or identical timestamps. - 🔴 Assuming
tm_wday/tm_ydayare pre-filled: They are only guaranteed valid afterlocaltime(),gmtime(), ormktime()execution. - 🔴 Relying on
tm_isdst == 1: DST rules vary by region and change historically. Relying on hardcoded DST values breaks across timezones. - 🔴 Mixing UTC and local time:
gmtimeproduces UTCstruct tm,localtimeproduces system-local. Combining fields from both yields invalid calendar dates.
Performance & Alternatives
- Lightweight:
struct tmoccupies ~36-40 bytes. Parsing and normalization are fast on modern CPUs. - Normalization Cost:
mktime()performs timezone/DST database lookups. Repeated calls in tight loops can become a bottleneck. Cachetime_tresults when possible. - C23 Improvements: C23 introduces
timegmstandardization and improved timezone handling. Consider upgrading if platform supports it. - High-Precision Alternatives: For sub-second or monotonic timing, use
timespec(<time.h>) withclock_gettime(CLOCK_REALTIME, &ts). - Third-Party Libraries:
Howard Hinnant's date(C++),libuvtime APIs, orICUfor complex timezone/DST rules.struct tmlacks IANA timezone database integration.
Headers & Linking
#include <time.h>
- Standard Compliance: Available in all C standards (C89 through C23).
- POSIX Extensions:
localtime_r,gmtime_r,timegmrequire_POSIX_C_SOURCEor_GNU_SOURCEdefines on Unix-like systems. - No External Linking: Functions operating on
struct tmreside in the standard C library. No special compiler flags required.
1. C srand() Function – Understanding Seed Initialization
https://macronepal.com/aws/understanding-the-c-srand-function
Explanation:
This article explains how the srand() function is used in C to initialize the pseudo-random number generator. In C, random numbers generated by rand() are not truly random—they follow a predictable sequence. srand() sets the starting “seed” value for that sequence. If you use the same seed, you will always get the same sequence of numbers. Developers often use time(NULL) as the seed to ensure different results each time the program runs.
2. C rand() Function Mechanics and Limitations
https://macronepal.com/aws/c-rand-function-mechanics-and-limitations
Explanation:
This article describes how the rand() function generates pseudo-random numbers in C. It returns values between 0 and RAND_MAX. The function is deterministic, meaning it produces the same sequence unless the seed is changed using srand(). It also highlights limitations such as poor randomness quality, predictability, and why rand() is not suitable for cryptographic or security-critical applications.
3. C log() Function
https://macronepal.com/aws/c-log-function-2
Explanation:
This guide covers the log() function in C, which calculates the natural logarithm (base e) of a number. It belongs to the <math.h> library. The article explains syntax, usage, and examples, showing how log(x) is used in scientific computing, mathematics, and engineering applications. It also discusses domain restrictions (input must be positive).
4. Mastering Date and Time in C
https://macronepal.com/aws/mastering-date-and-time-in-c
Explanation:
This article explains how C handles date and time using the <time.h> library. It covers functions like time(), clock(), difftime(), and structures such as struct tm. It also shows how to format and manipulate time values, making it useful for logging events, measuring program execution, and working with timestamps.
5. Mastering time_t Type in C
https://macronepal.com/aws/mastering-the-c-time_t-type-for-time-management
Explanation:
This article focuses on the time_t data type, which represents time in C as seconds since the Unix epoch (January 1, 1970). It explains how time_t is used with functions like time() to get current system time. It also shows conversions between time_t and readable formats using localtime() and gmtime().
6. C exp() Function Mechanics and Implementation
https://macronepal.com/aws/c-exp-function-mechanics-and-implementation
Explanation:
This article explains the exp() function in C, which computes eˣ (Euler’s number raised to a power). It is part of <math.h> and is widely used in exponential growth/decay problems, physics, finance, and machine learning. The article also discusses how the function is implemented internally and its numerical behavior.
7. C log() Function (Alternate Guide)
https://macronepal.com/aws/c-log-function
Explanation:
This is another guide on the log() function, reinforcing how natural logarithms work in C. It compares log() with log10() and shows when to use each. It also includes practical examples for mathematical calculations and real-world scientific usage.
8. Mastering log10() Function in C
https://macronepal.com/aws/mastering-the-log10-function-in-c
Explanation:
This article explains the log10() function, which calculates logarithm base 10. It is commonly used in engineering, signal processing, and scientific notation conversions. The guide shows syntax, examples, and differences between log() (natural log) and log10().
9. Understanding the C tan() Function
https://macronepal.com/aws/understanding-the-c-tan-function
Explanation:
This article explains the tan() function in <math.h>, which computes the tangent of an angle (in radians). It includes usage examples, mathematical background, and notes about input constraints (such as undefined values at certain angles like π/2).
10. Mastering Random Numbers in C (Secure vs Predictable)
https://macronepal.com/aws/mastering-c-random-numbers-for-secure-and-predictable-applications
Explanation:
This guide explains how random number generation works in C, including differences between predictable pseudo-random generators (rand()) and more secure or system-based randomness methods. It also discusses when randomness matters (games, simulations vs cryptography) and why rand() is not secure.
11. Free Online C Code Compiler
https://macronepal.com/aws/free-online-c-code-compiler-2
Explanation:
This article introduces an online C compiler that allows you to write, compile, and run C programs directly in the browser. It is useful for beginners who don’t want to install GCC or set up a local development environment. It supports quick testing of C code snippets.