gpt4 book ai didi

c++ - 如何将 UTC 时间戳转换为本地时间,一小时后的秒数?

转载 作者:搜寻专家 更新时间:2023-10-31 02:08:17 25 4
gpt4 key购买 nike

我有一个大型数据集,其时间戳为 UTC 时间(以毫秒为单位)。我正在将此数据集与另一个具有每小时微秒时间戳的数据集同步,因此我需要将第一个时间转换为本地时间,以每小时过去的秒数为单位。

我读过的关于这个主题的大多数类似问题都从获取当前时间的 time() 函数中获取 UTC 时间。

我已经尝试实现以下从 C++ Reference 中提取的内容.

我试图转换的时间戳是 double 的,但我不确定如何实际使用这个值。

我的数据集中的一个示例 ts:1512695257869

int main ()
{
double my_utc_ts; //value acquired from the data set

time_t rawtime;
struct tm * ptm;

time ( &rawtime ); //getting current time
//rawtime = my_utc_ts; //this is what I tried and is wrong, and results in a nullptr

ptm = gmtime ( &rawtime );

puts ("Current time around the World:");
printf ("Phoenix, AZ (U.S.) : %2d:%02d\n", (ptm->tm_hour+MST)%24, ptm->tm_min);

return 0;
}

在我能够将其转换为可用的 gmtime 对象或其他任何东西之后,我需要在一小时后获得秒数......我想如果我能让 UTC 时间戳成功转换,我将能够弄清楚这部分,但我没想到这么远。

指导将不胜感激。提前致谢。

最佳答案

After I'm able to convert it to a usable gmtime object or whatever, I need to get seconds past the hour...



以下是如何使用基于 <chrono>Howard Hinnant's, free, open-source, C++11/14/17 timezone library 将表示自 1970-01-01 00:00:00 UTC 以来的毫秒数的 double 数转换为本地小时后的秒数:
#include "date/tz.h"
#include <iostream>

int
main()
{
using namespace std::chrono;
using namespace date;
double my_utc_ts = 1512695257869;
using ms = duration<double, std::milli>;
sys_time<milliseconds> utc_ms{round<milliseconds>(ms{my_utc_ts})};
auto loc_s = make_zoned(current_zone(), floor<seconds>(utc_ms)).get_local_time();
auto sec_past_hour = loc_s - floor<hours>(loc_s);
std::cout << utc_ms << " UTC\n";
std::cout << sec_past_hour << " past the local hour\n";
}

这为我输出:
2017-12-08 01:07:37.869 UTC
457s past the local hour

如果您的本地时区不是与 UTC 偏移的整数小时,则输出的第二行对您来说将有所不同。

代码说明:

我们从您的输入 my_utc_ts 开始。

下一行创建了一个自定义 std::chrono::duration,它以 double 作为表示,以 milliseconds 作为精度。这种类型别名被命名为 ms

下一行构造 utc_ms,它是一个 std::chrono::time_point<system_clock, milliseconds>,包含 1512695257869,表示时间点 2017-12-08 01:07:37.869 UTC。到目前为止,还没有进行实际的计算。只需将 double 1512695257869 转换为表示自 1970-01-01 00:00:00 UTC 以来整数毫秒的类型。

此行开始计算:
auto loc_s = make_zoned(current_zone(), floor<seconds>(utc_ms)).get_local_time();

这将创建一个能够在 UTC 和本地时间之间映射的 {time_zone, system_time} 对,使用 time_zone 作为该映射。它使用 current_zone() 查找计算机的当前时区,并将时间点 utc_ms 从毫秒精度截断到秒精度。最后,尾随的 .get_local_time() 从此映射中提取本地时间,精度为秒,并映射到当前时区。也就是说, loc_s 是自 1970-01-01 00:00:00 UTC 以来的秒数,由您的本地时区的 UTC 偏移量抵消,该偏移量在 2017-12-08 01:07:37 UTC 有效。

现在,如果您将 loc_s 截断为小时的精度,并从 loc_s 中减去该截断的时间点,您将获得本地小时后的秒数:
auto sec_past_hour = loc_s - floor<hours>(loc_s);

整个计算只是上面的两行代码。接下来的两行简单地输出 utc_mssec_past_hour

假设您的本地时区在 2017-12-08 01:07:37 UTC 与 UTC 偏移了整数小时,您可以仔细检查:
457 == 7*60 + 37

实际上,如果您可以假设您的本地时区始终与 UTC 偏移整数小时,则可以通过根本不映射到本地时间来简化上述程序:
sys_time<milliseconds> utc_ms{round<milliseconds>(ms{my_utc_ts})};
auto utc_s = floor<seconds>(utc_ms);
auto sec_past_hour = utc_s - floor<hours>(utc_s);

结果将是相同的。

(警告:并非所有时区都与 UTC 偏移整数小时)

如果已知您的数据库是使用不是计算机当前本地时区的时区生成的,则可以通过将 current_zone() 替换为您的数据库生成时使用的 IANA 时区标识符来考虑这一点,例如:
auto loc_s = make_zoned("America/New_York", floor<seconds>(utc_ms)).get_local_time();

更新

整个库基于 C++11 引入的 std <chrono> 库。 utc_msloc_s 上面的类型是 std::chrono::time_point 的实例化,并且 sec_past_hour 具有 std::chrono::seconds 类型(它本身就是 std::chrono::duration 的实例化)。
duration 可以使用 .count() 成员函数转换为它们的“表示”类型。对于 seconds ,此表示类型将是带符号的 64 位整数。

有关 <chrono> 的更详细视频教程,请参阅此 Cppcon 2016 presentation 。本演示文稿将鼓励您尽可能避免使用 .count() 成员函数。

例如,不是将 sec_past_hour 转换为 long 以便您可以将其与数据集的其他值进行比较,而是将数据集的其他值转换为 std::chrono::duration 以便您可以将它们与 sec_past_hour 进行比较。

例如:
long other_data = 123456789;  // past the hour in microseconds
if (microseconds{other_data} < sec_past_hour)
// ...

此片段显示 <chrono> 将如何为您处理单位转换。这意味着您不会犯错误,例如当您应该乘以除以 1,000,000 时,或者用错误数量的零拼写“百万”。

关于c++ - 如何将 UTC 时间戳转换为本地时间,一小时后的秒数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47723668/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com