uint64_t timestamp_nanoseconds = 634019142119225390;
time_t result = timestamp_nanoseconds / 1000000000;
struct tm * timeinfo = gmtime(&result);
struct tm dateInfo ;
dateInfo.tm_mday = timeinfo->tm_mday ;
dateInfo.tm_mon = timeinfo->tm_mon ;
dateInfo.tm_year = timeinfo->tm_year ;
dateInfo.tm_hour = 0 ;
dateInfo.tm_min = 0 ;
dateInfo.tm_sec = 0 ;
time_t NoOfSecInDate = mktime ( &dateInfo );
从以纳秒为单位的输入时间戳,我们可以得到日期,如在 dateInfo 结构中设置的代码所示。从那时起,我们需要找到从输入日期的午夜开始耗时(以秒为单位)。
我们得到的输入是自 1970 年 1 月 1 日纪元以来耗时(以纳秒为单位)。例如,634019142119225390。我们从中提取时间设置为 00:00:00 的日期,我们需要找到表示经过的无符号整数中的耗时自 1970 年 1 月 1 日午夜 Unix 纪元 00:00 UTC 以来的纳秒时间。
解决方案应该针对任何给定的时间戳,而不是针对当前日期。
在上面的代码中,我们发现 mktime 函数需要大约 64 微秒才能完成,这是很多时间,这不是预期的
除了 mktime 函数之外,您是否还有其他替代方法可以实现相同的结果,即返回自纪元以来耗时(以秒为单位),但时间更短。
最佳答案
这可以通过 <chrono>
高效地完成和 Howard Hinnant's free, open-source, date-time library .
给定:
uint64_t timestamp_nanoseconds = 634019142119225390;
形成一个std::chrono::time_point
基于 system_clock
和 nanoseconds
.日期时间库使用此类类型的模板类型别名使这变得非常容易:
sys_time<nanoseconds> ts{nanoseconds{timestamp_nanoseconds}};
接下来您可以截断这个纳秒级精度的 time_point
到 days
精度 time_point
与:
auto sd = floor<days>(ts);
sd
是 system_clock
time_point
计算纪元以来的天数(而不是纳秒)。接下来你可以转换sd
进入year_month_day
,这正是它听起来的样子:a {year, month, day}
每个字段都有 getter 的结构:
year_month_day ymd = sd;
这个问题的相关部分,这就是你如何从午夜开始获得纳秒数:
auto tod = ts - sd;
如果你想要以秒为单位,它
auto tod = duration_cast<seconds>(ts - sd);
总而言之,从 uint64_t
开始纳秒数,以当天 (UTC) 的秒数计算,并对其计时,它是:
auto t0 = steady_clock::now();
sys_time<nanoseconds> ts{nanoseconds{timestamp_nanoseconds}};
auto tod = duration_cast<seconds>(ts - floor<days>(ts));
auto t1 = steady_clock::now();
给定输入 634019142119225390,并在 macOS 上使用 clang 在 -O3 处编译它,结果为:
tod == 15942s
大约需要 200ns。
由于使用了 floor<days>
,此公式对正 和负 输入均能正常工作,而不是 duration_cast<days>
.例如 -1'000'000'000
的输入给出一天中的时间 86399s
.
关于c++ - 在 C++ 中替代 mktime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45456618/