使用 c++ 将纪元毫秒转换为 UTC 日期和时间

Posted

技术标签:

【中文标题】使用 c++ 将纪元毫秒转换为 UTC 日期和时间【英文标题】:Convert Epoch Milliseconds to UTC Date and Time using c++ 【发布时间】:2020-12-04 17:59:56 【问题描述】:

我可以得到当前纪元的毫秒数:

#include <chrono>
#include <cstdint>
#include <iostream>
#include <ctime>

uint64_t timeSinceEpochMillisec() 
  using namespace std::chrono;
  return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();


int main() 
  std::cout << timeSinceEpochMillisec() << std::endl;
  return 0;

这将输出:1597436329290。

我有一个 sn-p 代码,它使用以秒为单位的纪元时间,效果很好。如何使用 timeSinceEpochMillisec() 使用 strftime 格式化日期和时间?

std::time_t epoch_timestamp = std::time(nullptr);
char buf[80];

std::tm *ts = std::gmtime(&epoch_timestamp);
strftime(buf, sizeof(buf), "%m/%d/%Y %H:%M:%S", ts);
std::cout << buf << std::endl;

输出:

1597437386198
08/14/2020/ 20:36:26

【问题讨论】:

【参考方案1】:

不幸的是,chrono 库只处理时间,而不处理日期。似乎是things will change in C++20,但现在我们必须使用来自ctime 库的函数和类型。

也就是说,一旦您使用SomeClock::now() 获得当前时间,您就可以使用to_time_t 将其转换为std::time_t,来自ctime 库。之后不再涉及 chrono 库,只有 ctime 库。

请参阅 this 和 this *** 问题。

std::time_t 通常只是自 1970 年 1 月 1 日 00:00 UTC 以来经过的数。您的 timeSinceEpochMillisec 函数类似,但它给出了毫秒数。 如果将其输出除以 1000 并得到整数结果,您可能会得到与 std::time(nullptr) 相同的数字,但这可能取决于实现(std::time_t 的定义可能不同)。

#include <chrono>
#include <cstdint>
#include <ctime>
#include <iostream>

using Clock = std::chrono::system_clock;

uint64_t timeSinceEpochMillisec() 
    using namespace std::chrono;
    return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();


int main() 
    auto now = Clock::now();

    // time_t comes from the C library and "it is generally implemented as an
    // integral value representing the number of seconds elapsed since 00:00
    // hours, Jan 1, 1970 UTC"
    // http://www.cplusplus.com/reference/ctime/time_t/
    auto now_in_time_t = Clock::to_time_t(now);

    // let's compare what we get with the current time converted to time_t and
    // your timeSinceEpochMillisec function
    std::cout << "Your functin: " << timeSinceEpochMillisec() << std::endl;
    std::cout << "time_t: " << now_in_time_t << std::endl;

    // Now let's work with dates. First we convert the current time to a date

    // Use std::localtime to convert the time_t to a "date", whose type is "tm*", where "tm" is a struct
    // Note that I'm using std::localtime instead of std::gmtime to get the date
    // in my local timezone. The std::gmtime gets the date in UTC.

    // https://en.cppreference.com/w/cpp/chrono/c/localtime
    auto now_as_tm_date = std::localtime(&now_in_time_t);

    // Now we can wuery the date struct for individual data
    // tm_year gives the number of years since 1900
    std::cout << "Current year is: " << now_as_tm_date->tm_year + 1900 << std::endl;
    // See http://www.cplusplus.com/reference/ctime/tm/
    // for other fields in the tm struct

    // The strftime function can be used to convert the date to a null
    // terminated char array for easy printing
    char buf[80];
    strftime(buf, sizeof(buf), "%m/%d/%Y %H:%M:%S", now_as_tm_date);
    std::cout << "Current date and time: " << buf << std::endl;
    return 0;

运行下面的代码并查看 cmets。

【讨论】:

谢谢,这解决了我最初的很多问题。是否能够使用包含毫秒的 strftime,就像使用 %m/%d/%Y %H:%M:%S.%f 来自strftime 的文档我认为这是不可能的。您也可以只查询tm 结构的字段,而不是使用strftime。但是,tm 结构也不存储毫秒,仅存储秒。因此,您可能需要存储从 chrono 库中获得的原始毫秒数,并在您确实需要打印毫秒数时使用它。

以上是关于使用 c++ 将纪元毫秒转换为 UTC 日期和时间的主要内容,如果未能解决你的问题,请参考以下文章

将纪元时间(以毫秒为单位)转换为时间戳到 UTC 错误

如何使用 Perl 将纪元时间转换为 UTC 时间?

将 UTC 纪元转换为本地日期

在纪元中转换日期格式

使用 strftime 将 python 日期时间转换为纪元

Angularjs日期过滤器将时间毫秒转换为UTC不起作用