【发布时间】:2019-09-11 13:11:06
【问题描述】:
我需要使用无符号字符的纯 ByteBuffer 的最小长度将 UTC 日期时间实例从 java 序列化为 c++。 我需要能够支持最小纳秒精度的时间点。
从 java 方面,我查看了 ZonedDateTime 和 OffsetDateTime 类,并查看了它们用于存储时间的原语类型,总共等于 17 个字节,这有点多。
请注意,我在这里并没有转移区域本身,因为我还没有找到将这些区域字符串从 IANA 映射到整数的方法。因此,我想区域偏移量就足够了。由于买方在将其发送到服务器之前必须将其时间点转换为特定的偏移量,因此可以说这将是 UTC 0。我正在寻找一种解决本地时间问题的解决方案,即不涉及 NTP 服务器!
java端是这样的:
// 4 byte
Integer year = offsetDateTime.getYear();
// 1 byte
Integer month = offsetDateTime.getMonthValue();
// 1 byte
Integer day = offsetDateTime.getDayOfMonth();
// 1 byte
Integer hour = offsetDateTime.getHour();
// 1 byte
Integer minutes = offsetDateTime.getMinute();
// 1 byte
Integer seconds = offsetDateTime.getSecond();
// 4 byte
Integer nanoSeconds = offsetDateTime.getNano();
// 4 byte
Integer utcZoneTimeTotalSecondsOffset = offsetDateTime.getOffset().getTotalSeconds();
在 c++ 方面,我需要做同样的事情,并且能够从上面的所有整数构造一个时间点。 除了 utcOffset 即最后一个整数之外,我已经找到了如何获取上述信息。
我想使用 chrono 来消耗这个缓冲区并从中实例化一个时间点。但是我无法找到在 C++ 中获取时间偏移的方法。如何使用 chrono 获取时间偏移,然后根据上述信息构造一个时间点?
auto now = std::chrono::system_clock::now();
time_t itt = std::chrono::system_clock::to_time_t(now);
tm utc_tm = *gmtime(&itt);
std::cout << utc_tm.tm_year + 1900 << '-';
std::cout << utc_tm.tm_mon + 1 << '-';
std::cout << utc_tm.tm_mday << ' ';
std::cout << utc_tm.tm_hour << ':';
std::cout << utc_tm.tm_min << ':';
std::cout << utc_tm.tm_sec << '\n';
? wher is the time zoneOffset here ?
如果我使用
utc_tm.tm_gmtoff
这给了我错误的信息。至少在我的情况下。所以我相信 gmtoff 不是要走的路,但如果 gmtoff 不是路,那又是什么呢?
【问题讨论】:
-
看起来在 C++ 中我们没有时区。直到 C++20 使用的时区是特定于实现的,之后它看起来应该是 UTC。
-
在 C++ 中,最终产品是 UTC 时间点还是本地时间点?
-
一个 UTC 时间点可以用 C++ 表示一个纳秒精度的时间点,总共使用 8 个字节,只要时间点大约在 1678 年到 2262 年的范围内。如果需要时区或UTC 偏移量,这将需要更多存储空间。
-
为什么要处理偏移量?只需使用 UTC ZoneId 创建 OffsetDateTime 或 ZonedDateTime。
-
如果所有客户端/服务器总是以 UTC 相互通信,那么比较时间戳就变得非常容易了。当然,除非出于某种原因,我们必须知道时间戳是否在客户端/服务器的本地时间打开/关闭期间。