2

I try to convert the following time string to epoch in milliseconds

"2022-09-25T10:07:41.000Z"

i tried the following code which outputs only epoch time in seconds (1661422061) how to get the epoch time in milliseconds.

#include <iostream>
#include <sstream>
#include <locale>
#include <iomanip>
#include <string>

int main()
{
    int tt;
    std::tm t = {};
    std::string timestamp = "2022-09-25T10:07:41.000Z";
    std::istringstream ss(timestamp);

    if (ss >> std::get_time(&t, "%Y-%m-%dT%H:%M:%S.000Z"))
    {
        tt = std::mktime(&t);
        std::cout << std::put_time(&t, "%c") << "\n"
                  << tt << "\n";
    }
    else
    {
        std::cout << "Parse failed\n";
    }
    return 0;
}
V_J viji
  • 39
  • 1
  • 7
  • There is no library function for this. You must write a few lines of simple, basic code, yourself that parses the milliseconds value from the string. Nothing more complicated than basic string parsing logic. – Sam Varshavchik Aug 25 '22 at 11:29
  • Yeah the problem with `std::get_time` is that it only has seconds resolution. Couldn't find quickly any clean way to have it in `ms`, [here](https://stackoverflow.com/questions/49712807/how-to-convert-a-datetime-string-with-milliseconds-to-unix-timestamp) they suggest to just convert to seconds * 1000 and add remaining `*.xxx` part of ms. – pptaszni Aug 25 '22 at 11:30
  • @SamVarshavchik There actually is support for this in C++20. Only not using `std::tm` but with a `chrono::time_point`. – Ted Lyngmo Aug 25 '22 at 11:58

1 Answers1

5

You can use the C++20 features std::chrono::parse / std::chrono::from_stream and set the timepoint to be in milliseconds.

A modified example from my error report on MSVC on this subject which uses from_stream:

#include <chrono>
#include <iostream>
#include <locale>
#include <sstream>

int main() {
    std::setlocale(LC_ALL, "C");
    std::istringstream stream("2022-09-25T10:07:41.123456Z");

    std::chrono::sys_time<std::chrono::milliseconds> tTimePoint;
    std::chrono::from_stream(stream, "%Y-%m-%dT%H:%M:%S%Z", tTimePoint);

    std::cout << tTimePoint << '\n';
    
    auto since_epoch = tTimePoint.time_since_epoch();
    std::cout << since_epoch << '\n';                 // 1664100461123ms

    // or as                                             1664100461.123s
    std::chrono::duration<double> fsince_epoch = since_epoch;
    std::cout << std::fixed << std::setprecision(3) << fsince_epoch << '\n';
}

Demo


If you are stuck with C++11 - C++17 you can install the date library by Howard Hinnant. It's the base of what got included in C++20 so if you upgrade to C++20 later, you will not have many issues.

#include "date/date.h"

#include <chrono>
#include <iostream>
#include <sstream>

int main() {
    std::istringstream stream("2022-09-25T10:07:41.123456Z");

    date::sys_time<std::chrono::milliseconds> tTimePoint;
    date::from_stream(stream, "%Y-%m-%dT%H:%M:%S%Z", tTimePoint);

    auto since_epoch = tTimePoint.time_since_epoch();

    // GMT: Sunday 25 September 2022 10:07:41.123
    std::cout << since_epoch.count() << '\n'; // prints 1664100461123
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • BTW, I always wondered if `set::setlocal()` is absolutely necessary? Or I need it for a reliable coding (for running program in different environments)? In addition, is `setlocal()` sets a per-process context like other environment variables? – Afshin Aug 25 '22 at 13:27
  • @Afshin The locale is `"C"` by default but when I wrote the ticket I though it best to add that just to show that the MRE I provided used the default. I think you need to open a question regarding the misc. details you wonder about :-) – Ted Lyngmo Aug 25 '22 at 13:30
  • Iam using C/C++ v1.15.5 and VS code to compile my program. When i compile the code the following error occurs namespace "std::chrono" has no member "sys_time" – V_J viji Aug 26 '22 at 05:18
  • Ok, compile it as C++20. What vendor has made that compiler? I don't recognize "C/C++ v1.15.5". Is that at Microsoft compiler? If so, use `/std:c++20` or `/std:c++latest` when compiling. Microsofts compiler defaults to C++14, that's why. – Ted Lyngmo Aug 26 '22 at 05:22
  • Sorry it is c++11 standard as mentioned in c_cpp_properties.json – V_J viji Aug 26 '22 at 05:41
  • @V_Jviji Can't you change it? If you're not allowed to change, you can install the library that is used as a base for many things in `chrono`. I updated the answer. – Ted Lyngmo Aug 26 '22 at 07:15
  • i try to change the compiler to c++20 through File -> Preferences -> Settings -> and searched for cppstandard and change it to c++20. but once i restart VS code the C_CPP_Properties.Json was not changed it remains in c++11 as cppstandard. – V_J viji Aug 26 '22 at 07:23
  • @V_Jviji Ok, sorry, I don't know VSCode well enough to guide you through that. Perhaps you could just change the JSON file manually before starting VSCode? Be careful so you don't break it though. Make a backup first. – Ted Lyngmo Aug 26 '22 at 07:27
  • @TedLyngmo i tried to install date/date.h library but error is coming in tz,h like fatal error: curl/curl.h: No such file or directory. installed curl through git clone in the powershell. but after that also same error is coming. – V_J viji Aug 27 '22 at 07:57
  • Ok, but the example I gave doesn't require the timezone library or curl. It only requires the `date.h` header. – Ted Lyngmo Aug 27 '22 at 08:49
  • @TedLyngmo: Issue solved. Got output. Thanks for your timely response. As you said i included date.h header file to headers folder of vscode project. And included #include "date.h" in main.cpp – V_J viji Aug 27 '22 at 09:58
  • @V_J viji Great! Your welcome! – Ted Lyngmo Aug 27 '22 at 10:21