Search code examples
c++datetimetimec++17utc

What is the correct way to get beginning of the day in UTC / GMT?


::tm tm{0, 0, 0, 29, 10, 2022 - 1900, 0, 0};  // 10 for November
auto time_t = ::mktime(&tm);
cout << "milliseconds = " << time_t * 1000 << endl;

Above code outputs 1669660200000, which is equivalent to 2022 November 29, 00:00:00. But it is in local timezone. How to get the UTC time for the aforementioned date?
A modern way with thread-safety will be appreciated.


Solution

  • There's a nit picky weak point in your solution (besides the thread safety issue): The members of tm are not guaranteed to be in the order you are assuming.

    The tm structure shall contain at least the following members, in any order.

    Using C++17 you can use this C++20 chrono preview library. It is free, open-source and header-only. Your program would look like:

    #include "date/date.h"
    #include <chrono>
    #include <iostream>
    
    int
    main()
    {
        using namespace std;
        using namespace chrono;
        using namespace date;
    
        sys_time<milliseconds> tp = sys_days{2022_y/11/29};
        cout << "milliseconds = " << tp.time_since_epoch().count() << '\n';
    }
    

    And the output would be:

    milliseconds = 1669680000000
    

    One of the nice advantages of using this library is that it will easily port to C++20. The C++20 version looks like:

    #include <chrono>
    #include <iostream>
    
    int
    main()
    {
        using namespace std;
        using namespace chrono;
    
        sys_time<milliseconds> tp = sys_days{2022y/11/29};
        cout << "milliseconds = " << tp.time_since_epoch() << '\n';
    }
    

    And outputs:

    milliseconds = 1669680000000ms
    

    Demo: