Ctime.h

time.h

The <time.h> header provides functions for working with calendar time and measuring elapsed CPU time. It's the standard toolkit for timestamps, simple benchmarking, and formatting dates for display.

time(): The Current Unix Timestamp

time(NULL) returns the number of seconds elapsed since the Unix epoch (00:00:00 UTC, January 1, 1970) as a time_t value. It's the standard way to get "what time is it right now" as a single, comparable number.

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

int main(void) {
    time_t now = time(NULL);
    printf("Seconds since epoch: %ld\n", (long)now);
    return 0;
}
clock(): Measuring CPU Time

clock() returns an implementation-defined count of "clock ticks" used by the program so far. Divide by CLOCKS_PER_SEC to convert that into seconds. This measures CPU time, not wall-clock time — if your program is asleep or waiting on I/O, that time typically doesn't count.

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

long fibonacci(int n) {
    if (n < 2) {
        return n;
    }
    return fibonacci(n - 1) + fibonacci(n - 2);
}

int main(void) {
    clock_t start = clock();

    long result = fibonacci(32);

    clock_t end = clock();
    double elapsedSeconds = (double)(end - start) / CLOCKS_PER_SEC;

    printf("fibonacci(32) = %ld\n", result);
    printf("Elapsed CPU time: %f seconds\n", elapsedSeconds);

    return 0;
}
difftime(): Comparing Two Timestamps

difftime(end, start) returns the difference between two time_t values, in seconds, as a double. It's the portable way to subtract timestamps, since time_t's internal representation isn't guaranteed to be a simple integer type you can subtract directly.

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

int main(void) {
    time_t start = time(NULL);

    /* ... some work happens here ... */
    for (volatile long i = 0; i < 200000000L; i++) { }

    time_t end = time(NULL);
    double seconds = difftime(end, start);

    printf("That took about %.0f second(s).\n", seconds);
    return 0;
}
Formatting Dates with strftime()

strftime() formats a broken-down time (struct tm) into a human-readable string using format specifiers similar to printf. First convert a time_t into a struct tm with localtime() (local time zone) or gmtime() (UTC), then format it.

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

int main(void) {
    time_t now = time(NULL);
    struct tm *localInfo = localtime(&now);

    char buffer[64];
    strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", localInfo);

    printf("Formatted local time: %s\n", buffer);
    return 0;
}
Common strftime Format Specifiers

Specifier

Meaning

Example

%Y

Four-digit year

2026

%m

Month (01-12)

07

%d

Day of month (01-31)

08

%H

Hour, 24-hour clock (00-23)

14

%M

Minute (00-59)

30

%S

Second (00-59)

00

%A

Full weekday name

Wednesday

%B

Full month name

July

Worked Example: Timing Code Execution

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

void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int main(void) {
    int data[5000];
    for (int i = 0; i < 5000; i++) {
        data[i] = 5000 - i; /* worst case: reverse-sorted */
    }

    clock_t start = clock();
    bubbleSort(data, 5000);
    clock_t end = clock();

    printf("Sorted %d elements in %f seconds of CPU time.\n",
           5000, (double)(end - start) / CLOCKS_PER_SEC);

    return 0;
}
Tip
`clock()` is fine for rough benchmarking, but its resolution and behavior around multi-threading are implementation-defined. For rigorous performance measurement, use platform-specific high-resolution timers such as POSIX `clock_gettime(CLOCK_MONOTONIC, ...)` or `QueryPerformanceCounter` on Windows.
Warning
Classic `localtime()` and `gmtime()` return a pointer to a **static internal buffer** that is overwritten on every call, which makes them **not thread-safe** — calling them concurrently from multiple threads can corrupt results. POSIX systems provide thread-safe variants, `localtime_r()` and `gmtime_r()`, which write into a caller-supplied `struct tm` instead.
Note
`time_t` and `struct tm` deliberately hide their internal representation — never assume `time_t` is a plain integer of seconds you can format directly. Always go through `localtime`/`gmtime` and `strftime` to convert it into something readable.