Convert Unix Timestamp in C++
C++ provides multiple ways to handle time: the legacy C-style <ctime> library and the modern, type-safe <chrono> library introduced in C++11 and significantly enhanced in C++20.
Using C++11 <chrono> (Recommended)
The std::chrono library provides a precision-neutral, type-safe way to handle time.
#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>
int main() {
using namespace std::chrono;
// 1. Get current Unix timestamp
auto now = system_clock::now();
// Convert to seconds (time_t)
auto now_sec = duration_cast<seconds>(now.time_since_epoch()).count();
std::cout << "Current timestamp (s): " << now_sec << std::endl;
// Convert to milliseconds
auto now_ms = duration_cast<milliseconds>(now.time_since_epoch()).count();
std::cout << "Current timestamp (ms): " << now_ms << std::endl;
// 2. Convert timestamp to Date string
time_t timestamp = 1704067200; // 2024-01-01 00:00:00 UTC
std::tm* tm_utc = std::gmtime(×tamp);
std::cout << "Date (UTC): " << std::put_time(tm_utc, "%Y-%m-%d %H:%M:%S") << std::endl;
// 3. Convert timestamp to system_clock::time_point
auto tp = system_clock::from_time_t(timestamp);
}Using C++20 <chrono> (Modern)
C++20 adds calendar and timezone support, making date manipulation much easier and readable.
#include <iostream>
#include <chrono>
#include <format> // Check compiler support
int main() {
using namespace std::chrono;
// Unix timestamp to year_month_day
long long timestamp = 1704067200;
auto tp = system_clock::time_point(seconds(timestamp));
year_month_day ymd{floor<days>(tp)};
std::cout << "Date: " << ymd << std::endl; // 2024-01-01
// Detailed formatting (requires std::format support)
// std::cout << std::format("{:%Y-%m-%d %H:%M:%S}", tp) << std::endl;
// Timezone conversion (requires <chrono> timezone db support)
/*
auto zt_nyc = zoned_time{"America/New_York", tp};
std::cout << "New York: " << zt_nyc << std::endl;
*/
}Legacy <ctime> (C-Style)
Useful for interacting with C APIs or simpler use cases.
#include <iostream>
#include <ctime>
int main() {
// Current timestamp
std::time_t result = std::time(nullptr);
std::cout << "Current timestamp: " << result << std::endl;
// Convert timestamp to string
std::time_t timestamp = 1704067200;
char buffer[80];
// Use thread-safe versions if available
struct tm time_info;
#if defined(_WIN32) || defined(_WIN64)
gmtime_s(&time_info, ×tamp); // Windows
#else
gmtime_r(×tamp, &time_info); // POSIX/Linux/Mac
#endif
std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S UTC", &time_info);
std::cout << buffer << std::endl;
}Common Pitfalls
Year 2038 Problem
On 32-bit systems, time_t is often a signed 32-bit integer, which will overflow on January 19, 2038. Modern 64-bit systems typically use a 64-bit time_t, which is safe for billions of years. Check sizeof(time_t) to be sure.
Thread Safety of gmtime / localtime
Standard std::gmtime and std::localtime return a pointer to a static internal buffer. They are not thread-safe. Always use the reentrant versions: gmtime_r / localtime_r (POSIX) or gmtime_s / localtime_s (Windows).
std::chrono::system_clock Epoch
Before C++20, the epoch of system_clock was not strictly specified to be the Unix epoch (1970-01-01), though strictly all major implementations used it. C++20 standardized it to the Unix epoch.
Frequently Asked Questions
Should I use <ctime> or <chrono> in C++?
Use <chrono> (C++11 and later) for type safety, precision, and modern design. Use <ctime> only when interfacing with legacy C APIs or when a simple time_t is sufficient and precision is not a concern.
How do I get the current Unix timestamp in milliseconds?
Use std::chrono::system_clock::now() and cast the duration to milliseconds using std::chrono::duration_cast.
Is time_t susceptible to the Year 2038 problem?
It depends on the platform and compiler. On modern 64-bit systems, time_t is usually a 64-bit integer, avoiding the problem. On 32-bit systems, it is typically 32-bit and will overflow in 2038.
How do I format a timestamp in C++?
In C++20, use std::format or std::chrono::format. In C++11/14/17, convert the time_point to time_t and use std::put_time or strftime.