<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.
Fundamentals
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);
Foundation
📝 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
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.
Cheat Sheet
⚡ Quick Reference
Function
Purpose
Typical use
time
Current epoch seconds
Timestamps, srand seed
localtime
Break into local fields
Display clock
gmtime
Break into UTC fields
Server logs
strftime
Format string
%Y-%m-%d %H:%M:%S
difftime
Seconds between times
Elapsed wall time
clock
CPU ticks
Benchmark 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
Hands-On
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(¤t_time) == (time_t)(-1)) {
fprintf(stderr, "time() failed\n");
return 1;
}
time_copy = *localtime(¤t_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;
}
📤 Output (example shape):
Current date and time: 2026-07-05 16:30:00
Epoch seconds: 1751721000
How It Works
time(¤t_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;
}
📤 Output (varies by CPU):
Elapsed (whole seconds): 0 or 1
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;
}
📤 Output (varies by CPU):
CPU time used: 0.0523 seconds
CLOCKS_PER_SEC = 1000
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.
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.
Built date: Monday, June 15 2026 09:30
Epoch: 1781505600
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.
Applications
🚀 Common Use Cases
Log timestamps — strftime on each log line.
File names — backup_%Y%m%d.dat from current time.
Timeouts — compare time(NULL) to a deadline.
Benchmarks — clock() around hot loops.
Random seeds — srand((unsigned)time(NULL)) in <stdlib.h> demos.
Age / duration — difftime 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.
Important
📝 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.
Performance
⚡ 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.
Wrap Up
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.
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
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about time.h
Dates, clocks, and durations in C.
5
Core concepts
💬01
time_t
Epoch sec.
Scalar
📚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.