【问题标题】:Serializing a datetime序列化日期时间
【发布时间】:2012-08-23 16:20:48
【问题描述】:

对日期/时间对执行二进制序列化的最佳方法是什么?

到目前为止,我最好的猜测是存储 POSIX time() 和 mktime() 函数返回的自纪元以来的秒数,然后在检索时使用 localtime() 将其转换回“人类可读”结构.

请注意,时间戳将由不同时区的计算机存储和检索。

【问题讨论】:

  • C 还是 C++?它们是不同的语言,我会在每种语言中使用不同的方法。
  • 您可以将boost::date_time 与`boost::serialization. Or if you don't want to use Boost, the C++11 standard library provides a chrono` 标头结合起来,它定义了可以轻松序列化的std::chrono::durationstd::chrono::timepoint

标签: c++ time c++11


【解决方案1】:

这在一定程度上取决于您对哪些数据感兴趣:

  • 您需要亚秒级精度吗?显然,POSIX time_t 通常不提供这一点,除非您使用某种浮点类型(它可能会引入自己的问题)。其他语言和库的时间格式(例如 JavaScript 和 Java)使用毫秒自固定日期而不是秒自固定时期来解决此问题。
  • 如果要跨时区存储和检索时间戳,那么使用定义为相对于纪元的格式(如 POSIX time_tJavaScript Data)可能比存储本地时间 + 时区更好。
  • 如果您需要知道原始时区,那么您也需要存储它。
  • 由于year 2038 problem,如果您使用诸如POSIX time_t 之类的东西,您需要将其存储为64 位数字,而不是32 位数字。 (即使您将其存储为 64 位数字,请记住您的 C 运行时的 mktimelocaltime 实现可能不支持 64 位 time_t 值。)

特别是关于 2038 年的问题:我不知道有任何 POSIX API 可以保证处理它。如果你想要一个可以保证处理它的库,你最好使用boost::date_time 之类的东西。 Project 2038 FAQ 包含有关测试 C 运行时是否支持 2038 的信息。根据该页面,现代 64 位 Linux 系统不应受到影响。 Visual C++ 的最新版本也不受影响。 (See here.) 即使您的库当前不支持 64 位 time_t 值,您也可以序列化 64 位 int 并将其转换为 32 位来处理它;这样,您的磁盘数据结构至少会合规,并且您的库有望在 2038 年成为问题之前得到更新。

【讨论】:

  • 不,我不需要亚秒级精度,但我想妥善处理 2038 年...我有什么选择? time_t 在 64 位系统上是 64 位长,还是有其他 POSIX API 来处理这个?
  • @cyberguijarro - 我在 2038 年添加了一些细节。
【解决方案2】:

请注意,时间戳将由不同时区的计算机存储和检索。

您是否也需要存储该时区?您对存储时的本地日期和时间感兴趣,还是只对即时时间感兴趣?

基本上,找出哪些信息对您很重要,并确保将其存储起来。

【讨论】:

  • 不,存储日期时间的时区并不重要,因为时区是用户定义的设置。实际的、普遍的、瞬间是最重要的。
  • @cyberguijarro:对,在这种情况下,“自 unix 纪元以来的秒数”是完全合理的(假设这是您开始获取数据的精度)。确保您非常明确地记录它:)
【解决方案3】:

你已经回答了自己。根据当地人的情况(即白天时间、时区、24 小时等),根据需要将计算机可理解的时间值转换为人类可读的格式是最好的。它的存储空间也很小。

【讨论】:

    【解决方案4】:

    这取决于您希望如何与二进制类型交互。如果总是使用 POSIX 函数,那么可以确定,一个 time_t 值就可以了。在 Windows 上,您需要将其转换为它们的格式以获取日期。当然,始终将二进制值保存为 UTC,不要对这个原始值应用任何偏移量。

    另一种方法(不是最快的)是存储一个字符串,而不是绑定到任何一个函数库。当然,如果您确定二进制值 1345739726 是使用 POSIX 调用创建的,那么如果将该值移动到 Windows 系统,则可以进行转换。字符串格式只是消除了关于表示什么时间点的任何问题。 string sTime = "Year:Month:MonthDay:WeekDay:Hour:Mintue:Second:Daylight:GMTOffset"

    【讨论】:

      猜你喜欢
      • 2016-08-18
      • 2012-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2017-11-29
      • 1970-01-01
      相关资源
      最近更新 更多