localtime() / gmtime() / mktime()
These functions convert between the time_t type and the struct tm structure (which breaks time down into individual fields such as year, month, day, hour, minute, and second). They are defined in <time.h>.
Syntax
// Converts a time_t value to a local-time struct tm (not thread-safe). // Returns a pointer to an internal static struct tm (overwritten on the next call). struct tm *localtime(const time_t *timer); // Converts a time_t value to a UTC struct tm (not thread-safe). // Returns a pointer to an internal static struct tm. struct tm *gmtime(const time_t *timer); // Converts a struct tm back to a time_t value (the inverse of localtime). // Returns the time_t value on success, or (time_t)(-1) on error. time_t mktime(struct tm *tm);
struct tm Members
| Member | Description | Range |
|---|---|---|
| tm_year | Year minus 1900. | e.g., 2024 → 124 |
| tm_mon | Month, zero-based. | 0–11 (0 = January) |
| tm_mday | Day of the month. | 1–31 |
| tm_hour | Hour. | 0–23 |
| tm_min | Minute. | 0–59 |
| tm_sec | Second. | 0–60 (includes leap seconds) |
| tm_wday | Day of the week (0 = Sunday). | 0–6 |
| tm_yday | Day of the year (days since January 1). | 0–365 |
| tm_isdst | Daylight saving time flag. | Positive: DST active, 0: standard time, negative: unknown |
Sample Code
#include <stdio.h>
#include <time.h>
int main(void) {
// Get the current time.
time_t now = time(NULL);
// Convert to local time using localtime.
struct tm *local = localtime(&now);
printf("Local time:\n");
printf(" %04d-%02d-%02d %02d:%02d:%02d\n",
local->tm_year + 1900, // tm_year is years since 1900, so add 1900.
local->tm_mon + 1, // tm_mon is zero-based, so add 1.
local->tm_mday,
local->tm_hour,
local->tm_min,
local->tm_sec);
// Display the day of the week as a string.
const char *weekdays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
printf(" Day of week: %s\n", weekdays[local->tm_wday]);
printf(" Day of year: %d\n", local->tm_yday + 1);
// Get UTC time using gmtime (9 hours behind Japan Standard Time).
struct tm *utc = gmtime(&now);
printf("UTC time: %02d:%02d:%02d\n", utc->tm_hour, utc->tm_min, utc->tm_sec);
// Convert a specific date and time to time_t using mktime.
struct tm target = {0}; // Zero-initialize all members.
target.tm_year = 2024 - 1900; // Year 2024
target.tm_mon = 0; // January (zero-based)
target.tm_mday = 1; // 1st
target.tm_hour = 0;
target.tm_min = 0;
target.tm_sec = 0;
time_t new_year = mktime(&target);
printf("Timestamp for Jan 1, 2024: %ld\n", (long)new_year);
return 0;
}
Notes
A common source of bugs with struct tm is that tm_year stores the year minus 1900, and tm_mon is zero-based. To display the correct year, use tm_year + 1900; for the correct month, use tm_mon + 1.
localtime() and gmtime() are not thread-safe. They return a pointer to an internal static buffer, so calling them simultaneously from multiple threads causes a data race. In multithreaded environments, use the POSIX extensions localtime_r() / gmtime_r() (or localtime_s() on Windows) instead.
mktime() automatically normalizes out-of-range values (for example, tm_mday = 32). January 32nd is corrected to February 1st. You can use this behavior to perform date arithmetic. In addition, mktime() automatically calculates and fills in tm_wday (day of the week) and tm_yday (day of the year).
To convert a time value to a string, use strftime() / asctime() / ctime(). For obtaining a time_t value, see time() / difftime() / clock().
If you find any errors or copyright issues, please contact us.