::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 c 17 way with thread-safety will be appreciated.
CodePudding user response:
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
CodePudding user response:
One old school C-style way is to first get the timezone difference and offset it with the value in the question.
static const auto TIMEZONE_OFFSET = [] (const ::time_t seconds)
{ // This method is to be called only once per execution
::tm tmGMT = {}, tmLocal = {};
::gmtime_r(&seconds, &tmGMT); // ::gmtime_s() for WINDOWS
::localtime_r(&seconds, &tmLocal); // ::localtime_s() for WINDOWS
return ::mktime(&tmGMT) - ::mktime(&tmLocal);
}(10000);
::tm tm{0, 0, 0, 29, 10, 2022 - 1900}; // set fields 1 by 1 as the order is not guaranteed
cout << " start of day = " << (::mktime(&tm) - TIMEZONE_OFFSET) << endl;