Iliketoproveit
Iliketoproveit

Reputation: 445

How to convert a datetime string with milliseconds to UNIX timestamp

I have the following string

2013-04-12 16:00:15.041

What is the C++ way to convert this string into a 64bit UNIX timestamp? Most question on here deal with only having the timestamp until seconds but in my case I also need to include the milliseconds.

Upvotes: 3

Views: 3069

Answers (1)

Davislor
Davislor

Reputation: 15164

Parse the string into its components and construct a std::chrono::time_point. In C++20, you will have the utc_clock in <chrono>, that is, a utc_time, or else std::chrono::local_t. In C++11 and up, you have std::chrono::system_clock.

There’s sort of a chicken-and-egg problem in converting the broken-down-time into STL time objects, though: usually, doing that gives you your answer with just the C library. You can use std::get_time(), on an istringstream if necessary, to convert your string to a tm and the C standard library function mktime() to convert the tm to a time_t, which you can then pass to std::chrono::system_clock::from_time_t()to convert to a std::chrono::time_point—except that, on UNIX/Linux, time_t is already a UNIX timestamp!

Your example has no time zone specified, so you might or might not need to do time-zone conversion.

The utc_clock uses the same Epoch as POSIX, January 1, 1970, so the time_since_epoch() member function of utc_time/time_point gives you the answer as a std::chrono::duration. If you are using system_clock instead, the Epoch is implementation-defined (but almost always the same Epoch, too), so you will want to find a time_point for 12:00 AM January 1, 1970, and subtract it from the time_point you calculate to get a duration. You can convert this duration, call it moment, into seconds with std::chrono::seconds(moment).count(). You can then convert to int64_t or uint64_t (from <cstdint>) if you want to be sure to have an exactly 64-bit value.

There are a few different UNIX time formats, but if you want to convert your time in milliseconds into a C/POSIX timespec with nanoseconds, rather than the obsolete formats in <sys/time.h>, set .tv_nsec to the number of milliseconds times one million, or convert from std::chrono::milliseconds to std::chrono::nanoseconds.

If the purpose of this is to work with filesystem timestamps, you might want std::filesystem::file_time_type.

Upvotes: 1

Related Questions