3

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.

Iliketoproveit
  • 445
  • 6
  • 15

1 Answers1

1

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.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Davislor
  • 14,674
  • 2
  • 34
  • 49
  • 1
    "*If you are on UNIX or Linux, you can use `getdate()` to convert your string to a `tm`*" - C++11 and later has [`std::get_time()`](http://en.cppreference.com/w/cpp/io/manip/get_time) to read a formatted date/time string from a `std::istream` into a `tm`. You can use `std::istringstream` for that stream, and `std::get_time()` is more flexible than `gettime()` – Remy Lebeau Apr 08 '18 at 04:52