C Standard Library time.h

Beginner
⏱️ 13 min read
📚 Updated: Jul 2026
🎯 5 Examples
<time.h>

What You’ll Learn

<time.h> lets C programs work with real-world clocks: stamp log entries, print today’s date, measure how long something took, or seed random numbers with time(NULL). You will use time_t for “seconds since epoch,” struct tm for calendar fields, and strftime for readable output.

01

time

Now (epoch).

02

struct tm

Y-M-D h:m.

03

localtime

Your zone.

04

strftime

Format text.

05

difftime

Elapsed sec.

06

clock

CPU time.

Definition and Usage

Calendar time counts forward from a fixed moment (the Unix epoch: 1970-01-01 00:00:00 UTC). time() returns that count as time_t. To show hours and minutes humans understand, convert with localtime or gmtime into struct tm, then format with strftime.

For benchmarking code, clock() measures processor time (ticks divided by CLOCKS_PER_SEC). For wall-clock delays between events, use time() and difftime().

💡
Beginner Tip

localtime and gmtime return pointers to shared static data. Copy into your own struct tm if you need two times at once: struct tm t = *localtime(&now);

📝 Syntax

Include the header:

C
#include <time.h>

Key types and macros

  • time_t — arithmetic type for calendar time (usually seconds since epoch)
  • struct tm — broken-down time: tm_year, tm_mon, tm_mday, tm_hour, etc.
  • clock_t — processor time ticks
  • CLOCKS_PER_SEC — ticks per second for clock()
  • NULL — pass to time(NULL) if you do not need to store the value yet

Common functions

  • time(&t) / time(NULL) — current calendar time
  • localtime(&t)struct tm * in local timezone
  • gmtime(&t)struct tm * in UTC
  • mktime(&tm) — convert struct tm (local) back to time_t
  • strftime(buf, size, format, &tm) — format date/time string
  • difftime(t1, t2)t1 - t2 in seconds as double
  • clock() — processor time used so far
  • ctime(&t) — quick string (non-reentrant; prefer strftime)

struct tm field notes

C
tm_year  /* years since 1900 — 2026 is 126 */
tm_mon   /* 0–11 — January is 0 */
tm_mday  /* 1–31 */
tm_hour  /* 0–23 */
tm_min, tm_sec

Common strftime specifiers

  • %Y — 4-digit year; %m month; %d day
  • %H — hour 00–23; %M minute; %S second
  • %I — hour 01–12 (12-hour clock); %p AM/PM
  • %A — full weekday name; %B full month name

Headers and linking

  • #include <time.h> — linked automatically on most systems.
  • Pairs with <stdio.h> for printing formatted times.
  • Compile: gcc program.c -std=c11 -o program.

⚡ Quick Reference

FunctionPurposeTypical use
timeCurrent epoch secondsTimestamps, srand seed
localtimeBreak into local fieldsDisplay clock
gmtimeBreak into UTC fieldsServer logs
strftimeFormat string%Y-%m-%d %H:%M:%S
difftimeSeconds between timesElapsed wall time
clockCPU ticksBenchmark loop
Now
time_t t = time(NULL);

Epoch sec

Format
%Y-%m-%d %H:%M:%S

ISO-like

Elapsed
difftime(t1, t0)

Seconds

CPU
clock()/CLOCKS_PER_SEC

Proc time

Examples Gallery

Compile with gcc file.c -std=c11 -o out. Date/time output depends on when and where you run the program.

📚 Getting Started

Print the current date and time from the reference.

Example 1 — Current Date and Time with strftime

From the reference: get time, convert to local, format as a string.

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

int main(void) {
    time_t current_time;
    struct tm time_copy;
    char buffer[80];

    if (time(&current_time) == (time_t)(-1)) {
        fprintf(stderr, "time() failed\n");
        return 1;
    }

    time_copy = *localtime(&current_time);

    if (strftime(buffer, sizeof(buffer),
                 "Current date and time: %Y-%m-%d %H:%M:%S",
                 &time_copy) == 0) {
        fprintf(stderr, "strftime buffer too small\n");
        return 1;
    }

    printf("%s\n", buffer);
    printf("Epoch seconds: %lld\n", (long long)current_time);

    return 0;
}

How It Works

time(&current_time) fills epoch seconds. localtime applies your timezone. We copy struct tm so the data stays valid. %H is 24-hour format; the reference’s %I:%M%p gives 12-hour with AM/PM.

Example 2 — difftime (Elapsed Seconds)

Measure wall-clock seconds between two time_t values.

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

int main(void) {
    time_t start = time(NULL);
    volatile unsigned long i;
    time_t end;

    for (i = 0; i < 300000000UL; i++) {
        /* busy work */
    }

    end = time(NULL);
    printf("Elapsed (whole seconds): %.0f\n", difftime(end, start));

    return 0;
}

How It Works

difftime(end, start) returns end - start as double. time() resolution is often one second—for sub-second timing use platform APIs or clock() for CPU time (see Example 3).

📈 Practical Patterns

CPU timing, UTC, and building times.

Example 3 — clock() for CPU Time

From the reference: measure processor time for a computation.

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

int main(void) {
    clock_t start = clock();
    volatile unsigned long i;
    clock_t end;
    double cpu_seconds;

    for (i = 0; i < 50000000UL; i++) {
        /* work */
    }

    end = clock();
    cpu_seconds = (double)(end - start) / (double)CLOCKS_PER_SEC;

    printf("CPU time used: %.4f seconds\n", cpu_seconds);
    printf("CLOCKS_PER_SEC = %ld\n", (long)CLOCKS_PER_SEC);

    return 0;
}

How It Works

Subtract clock_t values and divide by CLOCKS_PER_SEC. This measures CPU effort, not calendar waiting. A sleeping program may show little clock growth.

Example 4 — localtime vs gmtime (UTC)

Same instant, two timezone views.

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

int main(void) {
    time_t now = time(NULL);
    struct tm local = *localtime(&now);
    struct tm utc = *gmtime(&now);
    char buf_local[64];
    char buf_utc[64];

    strftime(buf_local, sizeof(buf_local), "Local: %Y-%m-%d %H:%M:%S", &local);
    strftime(buf_utc, sizeof(buf_utc),     "UTC:   %Y-%m-%d %H:%M:%S", &utc);

    printf("%s\n", buf_local);
    printf("%s\n", buf_utc);

    return 0;
}

How It Works

Both functions read the same time_t but interpret offsets differently. Copy each struct tm immediately—the next call to localtime/gmtime may overwrite static storage.

Example 5 — mktime (Build a Date)

Set calendar fields and convert back to epoch seconds.

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

int main(void) {
    struct tm t = { 0 };

    t.tm_year = 2026 - 1900;  /* 2026 */
    t.tm_mon  = 6 - 1;        /* June */
    t.tm_mday = 15;
    t.tm_hour = 9;
    t.tm_min  = 30;
    t.tm_sec  = 0;

    time_t when = mktime(&t);
    char buffer[64];

    if (when == (time_t)(-1)) {
        fprintf(stderr, "mktime failed\n");
        return 1;
    }

    strftime(buffer, sizeof(buffer), "Built date: %A, %B %d %Y %H:%M", &t);
    printf("%s\n", buffer);
    printf("Epoch: %lld\n", (long long)when);

    return 0;
}

How It Works

mktime treats struct tm as local time and normalizes overflow fields (e.g. minute 90 rolls hour). tm_year is years since 1900; tm_mon is 0-based months. Epoch value varies with timezone.

🚀 Common Use Cases

  • Log timestampsstrftime on each log line.
  • File namesbackup_%Y%m%d.dat from current time.
  • Timeouts — compare time(NULL) to a deadline.
  • Benchmarksclock() around hot loops.
  • Random seedssrand((unsigned)time(NULL)) in <stdlib.h> demos.
  • Age / durationdifftime between two dates as time_t.

🧠 How time.h Fits Together

1

Get time_t

time() returns seconds since epoch.

Scalar
2

Split into struct tm

localtime or gmtime for calendar fields.

Fields
3

Format or diff

strftime for text; difftime for elapsed seconds.

Output
=

Human-readable time

Machines count seconds; users see dates and durations.

📝 Notes

  • time_t overflow (Year 2038 on 32-bit) is a known issue—modern 64-bit time_t helps.
  • localtime/gmtime return static pointers—copy struct tm if needed.
  • tm_year is since 1900; tm_mon is 0–11 (January = 0).
  • time() resolution is often 1 second—not for high-precision timers.
  • clock() measures process CPU time, not wall time or sleep duration.
  • Daylight saving and timezones are OS-defined—test edge cases in production apps.

⚡ Optimization

Avoid calling time() or strftime inside tight inner loops. Cache formatted timestamps per second for logs. For micro-benchmarks, clock() or platform-specific high-resolution timers beat difftime. Store events as time_t or UTC epoch in databases; convert to local only for display.

Conclusion

<time.h> bridges machine time and human calendars. Use time for timestamps, localtime + strftime for display, difftime for elapsed seconds, and clock for CPU benchmarking.

Remember struct tm quirks and static pointer rules, and copy time structures when you need more than one at a time.

💡 Best Practices

✅ Do

  • Copy struct tm from localtime immediately
  • Use strftime with sizeof(buffer)
  • Check time() and mktime() for failure
  • Store/log UTC with gmtime when possible
  • Use %Y-%m-%d %H:%M:%S for sortable timestamps
  • Document whether times are local or UTC in your app

❌ Don’t

  • Assume localtime is thread-safe without copying
  • Treat tm_year as the full calendar year directly
  • Use time() for sub-millisecond precision
  • Confuse clock() with wall-clock stopwatch time
  • Ignore strftime return value 0 (buffer too small)
  • Rely on ctime in multi-threaded programs

Key Takeaways

Knowledge Unlocked

Five things to remember about time.h

Dates, clocks, and durations in C.

5
Core concepts
📚 02

struct tm

Y-M-D fields.

Calendar
📈 03

strftime

Format out.

Print
📄 04

difftime

Elapsed.

Delta
🌐 05

clock

CPU sec.

Bench

❓ Frequently Asked Questions

time.h is the C standard header for calendar time and CPU time. It provides time for the current epoch seconds, localtime and gmtime to break time into year/month/day fields, strftime to format dates as strings, difftime for elapsed seconds, and clock for processor time used by the program.
time_t is usually a scalar counting seconds since the Unix epoch (1970-01-01 UTC). struct tm holds human fields: tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, and more. Convert with localtime, gmtime, or mktime.
localtime converts a time_t to struct tm in the system's local timezone (with daylight saving when applicable). gmtime converts to UTC (Coordinated Universal Time). Use localtime for user-facing clocks; gmtime for logs in a universal reference.
clock returns an approximation of processor time consumed by the program, in clock ticks. Divide the difference by CLOCKS_PER_SEC to get seconds of CPU time. It is not the same as wall-clock time—sleeping or waiting on I/O may not advance clock much.
strftime writes a formatted date/time string from a struct tm into your buffer. Common specifiers: %Y year, %m month, %d day, %H hour (24h), %M minute, %S second. It returns characters written (excluding null) or 0 if the buffer is too small.
Standard C localtime and gmtime return pointers to static internal storage—each call may overwrite the previous result. For threads, copy into your own struct tm immediately, or use platform-specific re-entrant versions like localtime_r (POSIX).
Did you know?

POSIX adds clock_gettime and localtime_r for nanosecond resolution and thread-safe conversion—not part of standard C, but common on Linux and macOS. Portable C programs stick to time.h; servers often use POSIX extensions when available.

Explore C Standard Library Headers

Continue with wchar.h or browse the library index.

Standard Library Index →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful