C++中 mktime 的替代品
Alternative to mktime in C++
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 函数的方法,它可以实现相同的结果,即返回自 epoch 以来经过的时间(以秒为单位(,但时间更少。
这可以通过<chrono>
和Howard Hinnant的免费开源日期时间库非常有效地完成。
鉴于:
uint64_t timestamp_nanoseconds = 634019142119225390;
形成基于system_clock
和nanoseconds
的std::chrono::time_point
。 日期时间库通过此类类型的模板类型别名使这变得非常容易:
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
,这正是它听起来的样子:一个{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 上的 -O3 上使用 clang 编译它,这会导致:
tod == 15942s
大约需要 200ns。
由于使用了floor<days>
,而不是duration_cast<days>
,该公式将正确适用于正输入和负输入。 例如,输入-1'000'000'000
给出一天中86399s
的时间。
您正在尝试在同一UTC日期开始时获取时间。 为此,您可以在几秒钟内完成计算:
struct timezone tz = {0, 0};
struct timeval start, end;
gettimeofday(&start, &tz);
uint64_t timestamp_nanoseconds = 634019142119225390ULL;
time_t result = timestamp_nanoseconds / 1000000000ULL;
time_t day = result - (result % 86400);
gettimeofday(&end, &tz);
struct timeval dsec;
timersub(&end, &start, &dsec);
printf("calc took %ld sec %ld usec.n",
dsec.tv_sec, dsec.tv_usec, s);
printf("UTC: %s",asctime(gmtime(&now)));
printf("Day: %s",asctime(gmtime(&day)));
这花费的时间要少得多:
calc took 0 sec 1 usec. total 0.000000
UTC: Sat Feb 3 04:25:42 1990
Day: Sat Feb 3 00:00:00 1990
如果您想以当地时区获取一天的开始,您可以在计算day
中添加偏移量。
- C++中原子的替代品<variant>
- C++sscanf_s的替代品
- getline的替代品
- 什么是 std::function::argument_type 的替代品?
- MKTIME(&time_check) 仅返回"-1"
- 如何在不使用 std::tm 和 mktime() 的情况下为给定日历日期创建 chrono::time_point 对
- 有DirectShow的替代品吗?
- 智能指针作为 QObject::d eleteLater() 的替代品
- C++中 mktime 的替代品
- 对于C++,是否有任何现代的 std::strchr() 替代品?
- shared_future是<void>condition_variable的合法替代品吗?
- 如何导致 std::mktime 失败
- std :: mkTime返回-1在qnx上
- 这是山塔的替代品
- STD :: Referent_wrapper/std :: std :: vector的selution_ptr替代品
- 更好的替代品?
- 排序向量上 std::find_if 和 std::bind2nd 的替代品
- 提升勒让德多项式的 gsl_sf_legendre_sphPlm_array() 替代品
- mktime() 给出的结果与 Howard Hinnant 的日期库 (std::chrono based ) 不同
- 使用MKTime在C 中时期