Linux Time: The Epoch & time_t

Linux Time: The Epoch & time_t
Chapter 10 Series — Part 2: How Linux Stores Calendar Time
1970
Year Zero (Epoch)
2038
32-bit Overflow Year
time_t
Calendar Type

The Problem: How Do You Store a Date?

Storing a date like “15 May 2025, 10:30 AM” as a string wastes space, is language-dependent, and is terrible to compare or do maths with. UNIX solved this elegantly: store time as a single integer — the number of seconds since a fixed reference moment.

Keywords in This Post

Epoch time_t UTC Signed Integer Overflow Year 2038 Problem 32-bit vs 64-bit Embedded Systems

🌎 What is the UNIX Epoch?

The Epoch is the fixed reference point that UNIX chose as “time zero”. It is midnight, 1 January 1970, in UTC (Coordinated Universal Time).

Analogy: Think of a highway with kilometre markers. You measure your position from “KM 0” — that starting marker is the Epoch. Your current position (e.g., KM 1,747,123,456) is the number of seconds elapsed. Going back before the marker gives you negative numbers — that’s dates before 1970.

Date/Event Seconds since Epoch (approx.)
1 Jan 1970, 00:00:00 UTC 0
1 Jan 1971, 00:00:00 UTC 31,536,000
1 Jan 2000, 00:00:00 UTC 946,684,800
15 May 2025, 00:00:00 UTC ~1,747,267,200
19 Jan 2038, 03:14:07 UTC 2,147,483,647 (MAX for 32-bit signed)

💾 The time_t Data Type

Linux stores calendar time in a variable of type time_t, defined in <time.h>. It is simply an integer type — the number of seconds since the Epoch. You can print it, compare two of them, or subtract one from another.

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

int main(void)
{
    time_t t1 = 0;            /* Epoch itself: 1 Jan 1970 */
    time_t t2 = 86400;        /* One day later (86400 = 24 * 60 * 60) */
    time_t t3 = 1747267200;   /* Some time in May 2025 */

    /* How many seconds between t1 and t2? */
    long diff = (long)(t2 - t1);
    printf("Difference: %ld seconds\n", diff); /* prints 86400 */

    return 0;
}

On a 32-bit system, time_t is typically a 32-bit signed integer. On a 64-bit system, it is a 64-bit signed integer. This distinction is at the heart of the Year 2038 problem.

Architecture time_t size Maximum representable date
32-bit Linux 4 bytes (signed) 19 January 2038, 03:14:07
64-bit Linux 8 bytes (signed) 292 billion years from now

⚠ The Year 2038 Problem Explained

A signed 32-bit integer can hold values from -2,147,483,648 to +2,147,483,647. When time_t is a 32-bit signed integer and its value reaches 2,147,483,647, adding just one more second causes an integer overflow — the value wraps around to -2,147,483,648, which corresponds to 13 December 1901.

Analogy: Imagine an old car odometer that only shows 5 digits. Once it hits 99,999 km, the next kilometre rolls it back to 00,000 km. Anyone reading it thinks the car has barely been driven. The same thing happens with a 32-bit time_t on 19 January 2038.

/* Demonstration of the 2038 overflow (illustrative only) */
#include <stdio.h>
#include <stdint.h>

int main(void)
{
    int32_t t = 2147483647;   /* Maximum 32-bit signed value (2038 limit) */
    printf("Before overflow: %d\n", t);

    t = t + 1;                /* Adding 1 second wraps around */
    printf("After +1 second: %d\n", t);  /* prints -2147483648 ! */

    return 0;
}

System Type Risk Level Reason
64-bit desktop/server Linux Safe time_t is 64-bit, won’t overflow until ~292 billion years
32-bit embedded Linux (routers, industrial controllers) At Risk Long product lifespans, often not updated, 32-bit time_t
Legacy data & file formats with 32-bit timestamps Medium Risk Old binary formats storing int32_t timestamps; need migration

Embedded systems engineers take note: a motor controller programmed today with a 32-bit time_t that calculates future maintenance schedules could produce wrong dates after 2038 if still running. This is a real concern in industrial and automotive sectors.

🌐 UTC — Why Not Local Time?

UNIX stores time internally in UTC — not in any local timezone. This is deliberate. Consider a server that moves from New York to Tokyo — its files and logs should not suddenly show wrong timestamps. UTC is a stable, timezone-independent reference. Conversion to local time happens only when displaying time to the user.

Stored internally Displayed to user
time_t = 1747267200 (UTC) Converted to IST (+5:30), displayed as 15 May 2025, 05:30 AM

Up Next in This Series

Part 3 covers the gettimeofday() and time() system calls — how to actually read the current calendar time from your C program.

Next: gettimeofday() & time() → All Linux Posts

Leave a Reply

Your email address will not be published. Required fields are marked *