【问题标题】:Extract date timestamp from a timestamp in C++从 C++ 中的时间戳中提取日期时间戳
【发布时间】:2018-07-18 07:36:56
【问题描述】:

如何从时间戳中提取日期 (YYYY-MM-DD) 并将其保存为时间戳?
我们知道1518038663000Wednesday, 7 February 2018 16:24:23(GTM -5 小时) 但我想只保留Wednesday, 7 February 2018(GTM -5 小时) 并将其另存为1517979600000

【问题讨论】:

标签: c++ time timestamp unix-timestamp


【解决方案1】:

如果你愿意使用这个free, open-source time zone library,可以这样做:

#include "date/tz.h"
#include <iostream>

int
main()
{
    using namespace std::chrono;
    using date::operator<<;

    // set up the timestamp
    date::sys_time<milliseconds> ts{1518038663000ms};

    // create a zoned_time by pairing the timestamp with a time_zone
    auto zt = date::make_zoned("America/New_York", ts);

    // confirm what you have by printing out the timestamp and the local time
    std::cout << zt.get_sys_time().time_since_epoch() << '\n';
    std::cout << date::format("%A, %e %B %Y %T (%z)", zt) << "\n\n";

    // Truncate the zoned_time to the beginning of the local day
    zt = date::floor<date::days>(zt.get_local_time());

    // confirm what you have by printing out the timestamp and the local time
    std::cout << zt.get_sys_time().time_since_epoch() << '\n';
    std::cout << date::format("%A, %e %B %Y %T (%z)", zt) << '\n';
}

上面代码中的 cmets 描述了每一行代码在做什么。中间一行代码就是这个问题的实际答案:

    // Truncate the zoned_time to the beginning of the local day
    zt = date::floor<date::days>(zt.get_local_time());

这个程序输出:

1518038663000ms
Wednesday,  7 February 2018 16:24:23.000 (-0500)

1517979600000ms
Wednesday,  7 February 2018 00:00:00.000 (-0500)

【讨论】:

    【解决方案2】:

    显然,被称为时间戳的随机数只有在它们也有单位时才有价值。对于数字“1518038663000”等同于“2018 年 2 月 7 日星期三 16:24:23”,这意味着我们从纪元开始以毫秒为单位工作。给定这样的单位,我们可以将时间戳转换为chrono::durationconst chrono::milliseconds ts(1518038663000);

    我们需要从chrono::milliseconds 转换为代表天数的chrono::duration。不幸的是,chrono 库的最长period 的便利函数是hours,因此我们需要定义自己的chrono::duration。由于period 被定义为:

    每次滴答的秒数

    我们需要计算一天中的秒数,unfortunately that's not defined in the standard,但我们可以计算它:ratio&lt;86400&gt;(或者更明确地说:ratio_multiply&lt;chrono::hours::period, ratio&lt;24&gt;&gt;)。

    接下来我们需要决定要使用的四舍五入:What's the Difference Between floor and duration_cast? 但它可能是chrono::floor。所以我们将截断为天,然后转换回毫秒来存储值:

    const auto result = chrono::duration_cast<chrono::milliseconds>(chrono::floor<chrono::duration<int, ratio<86400>>>(ts))
    

    至于result 的输出格式,您需要使用put_time,这意味着您需要进行如下转换:

    const auto time = chrono::system_clock::to_time_t(chrono::system_clock::time_point(result));
    
    cout << put_time(localtime(&time), "%A,%e %B %Y");
    

    您要存储的时间戳为:result.count()

    Live Example

    【讨论】:

    • 如果你程序的输入是1518038663000,那么输出是1517979600000吗?如果不是,您输出的内容与 OP 报告的内容之间的差异的性质是什么?
    • @HowardHinnant 由于您对这个库的了解比我多,我假设您指出了仅依赖标准的潜在陷阱。我对天数的限制是绝对的,它不考虑 GMT 偏移量。如果需要保留这样的偏移量,则需要重新添加。这就像+ chrono::hours(5) 一样简单,因此您的result 计算将变为:const auto result = chrono::duration_cast&lt;chrono::milliseconds&gt;(chrono::floor&lt;chrono::duration&lt;int, ratio&lt;86400&gt;&gt;&gt;(ts)) + chrono::hours(5)coliru.stacked-crooked.com/a/27ae602bdae9004d
    猜你喜欢
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 2021-12-30
    相关资源
    最近更新 更多