Real Epoch Converter logo realepochconverter
programming guide

C++ Unix Timestamp: time(), chrono & the timegm/mktime gotcha

C++ has two eras: the C <time.h> functions (fast, but full of timezone and thread-safety traps) and std::chrono (type-safe since C++11, with clock conversion since C++20). This guide covers both, including the timegm-vs-mktime trap that shifts values by the local offset.

Get the current Unix timestamp

C++
#include <ctime>
#include <chrono>

// C-style: whole seconds
std::time_t sec = std::time(nullptr);        // 1767225600

// C++11+ chrono: seconds and milliseconds as typed durations
using namespace std::chrono;
auto now = system_clock::now();
auto s  = duration_cast<seconds>(now.time_since_epoch()).count();        // 1767225600
auto ms = duration_cast<milliseconds>(now.time_since_epoch()).count();   // 1767225600123

Convert a timestamp to a date

gmtime() gives a std::tm in UTC; localtime() in the process's configured timezone (set via tzset/TZ, not per-call). Both return pointers to shared static buffers — copy the std::tm immediately or use the _r variants. std::put_time formats it.

C++
#include <ctime>
#include <iomanip>
#include <sstream>

std::time_t ts = 1767225600;

std::tm utc = *std::gmtime(&ts);       // UTC — copy before any other call
std::ostringstream out;
out << std::put_time(&utc, "%Y-%m-%d %H:%M:%S");
std::string s = out.str();             // "2026-01-01 00:00:00"

// C++20: chrono can format directly
// std::cout << std::chrono::floor<std::chrono::seconds>(std::chrono::system_clock::from_time_t(ts));

Convert a date back to a timestamp

This is the trap. mktime() interprets the std::tm as local time; timegm() interprets it as UTC. The two differ by your timezone offset. timegm is not in the C standard (it is a POSIX/glibc extension) — on Windows, use _mkgmtime().

C++
#include <ctime>

std::tm t{};
t.tm_year = 2026 - 1900;
t.tm_mon  = 0;                 // January
t.tm_mday = 1;

std::time_t as_utc   = timegm(&t);    // 1767225600  — UTC (POSIX; _mkgmtime on Windows)
std::time_t as_local = mktime(&t);    // local-time interpretation — off by the offset

Naive vs aware: everything is naive unless you say so

  • std::time_t — an integer; no zone anywhere. Meaning is only as good as the convention that produced it (usually UTC).
  • std::tm — naive wall-clock fields; the conversion function (mktime vs timegm) decides the zone.
  • std::chrono time_point — also zone-less, but C++20's zoned_time adds explicit zones and DST-aware arithmetic.
  • Rule: store time_t (UTC by convention), convert to std::tm only for display, and use timegm/_mkgmtime on the way back.

Native precision: nanoseconds (chrono)

std::chrono::system_clock exposes whatever the OS clock provides — nanoseconds on Linux, ~100ns on Windows. C-style time() is whole seconds; get sub-second parts from clock_gettime(CLOCK_REALTIME, ...) or chrono, and combine with duration_cast rather than floating-point math.

Common pitfalls

  • mktime vs timegm — local vs UTC interpretation; the classic off-by-offset bug.
  • gmtime/localtime buffers — shared static state; the next call overwrites your struct (thread-unsafe too — use gmtime_r).
  • time_t is 32-bit on old platforms — 2038 wraps; compile 64-bit (time_t is 64-bit on all modern 64-bit targets).
  • chrono epochsystem_clock is Unix-epoch-based, but steady_clock is not — never mix them for timestamps.

Try it live

Verify values in the epoch converter, or copy the current timestamp from the C++ snippet tab on the homepage.

First published · Last reviewed · Maintained and developed by the Real Epoch Converter team · [email protected] · Contact · Methodology

Unix time in every language

JavaScript · Python · PHP · SQL · Go · Java · C# · Rust · C++ · PowerShell

Prefer the point-and-click version? The epoch time converter on the home page handles seconds, milliseconds, and microseconds in any timezone — every snippet on this page produces the same value that tool shows.

Copied