Boost C++ 库

…在世界上最受推崇和设计最精良的 C++ 库项目中之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

详细信息 - Boost C++ 函数库
PrevUpHomeNext

详细信息

计算

时间点 -- 时长 -- 间隔(周期) -- 特殊值处理

时间点

本节描述了时间点可以执行的一些基本算术规则。一般来说,时间点支持与时长结合的基本算术运算,如下所示:

      Timepoint + Duration  --> Timepoint
      Timepoint - Duration  --> Timepoint
      Timepoint - Timepoint --> Duration
    

与常规数字类型不同,以下操作是未定义的。

      Duration + Timepoint  --> Undefined
      Duration - Timepoint  --> Undefined
      Timepoint + Timepoint --> Undefined
    

时长

时长表示一段时间的长度,可以为正值和负值。能够与其他时长和简单整数值进行计算通常很有用。以下描述了这些计算:

      Duration + Duration  --> Duration
      Duration - Duration  --> Duration
      
      Duration * Integer   --> Duration
      Integer  * Duration  --> Duration
      Duration / Integer   --> Duration  (Integer Division rules)
    

间隔(周期)

间隔逻辑对于简化日期和时间的许多“计算”非常有用。以下描述了周期提供的基于半开区间的操作。以下操作会基于两个输入时间周期计算新的时间周期:

Timeperiod intersection Timeperiod --> Timeperiod 
  (null interval if no intersection)
Timeperiod merge Timeperiod        --> Timeperiod 
  (null interval if no intersection)
Timeperiod shift Duration          --> Timeperiod 
  (shift start and end by duration amount)
    

此外,周期还支持各种计算布尔结果的查询。第一组是与其他时间周期的计算:

  Timeperiod == Timeperiod           --> bool
  Timeperiod < Timeperiod            --> bool (true if lhs.last <= rhs.begin)
  Timeperiod intersects Timeperiod   --> bool
  Timeperiod contains Timeperiod     --> bool
  Timeperiod is_adjacent Timeperiod  --> bool 
    

以下计算是针对时间点执行的。

  Timeperiod contains Timepoint      --> bool
  Timeperiod is_before Timepoint     --> bool
  Timeperiod is_after Timepoint      --> bool 
    

特殊值处理

对于许多时间问题,时长和时间点类型支持特殊值(如“非日期时间”(NADT)和无穷大)是很有用的。一般来说,特殊值(如“非日期时间”(NADT)和无穷大)应该遵循浮点值的规则。请注意,应该可以配置基于 NADT 的系统,使其抛出异常而不是产生 NADT。

  Timepoint(NADT) + Duration --> Timepoint(NADT)
  Timepoint(∞) + Duration    --> Timepoint(∞)
  Timepoint + Duration(∞)    --> Timepoint(∞)
  Timepoint - Duration(∞)    --> Timepoint(-∞)
    

当对正负无穷大执行操作时,库将产生与以下一致的结果。

  Timepoint(+∞) + Duration(-∞) --> NADT
  Duration(+∞) + Duration(-∞)  --> NADT
  Duration(±∞) * Zero          --> NADT
  
  Duration(∞) * Integer(Not Zero) --> Duration(∞)
  Duration(+∞) * -Integer         --> Duration(-∞)
  Duration(∞) / Integer           --> Duration(∞)
    

设计目标

类别 描述
函数
接口 提供用于日期和时间操作的具体类
  • date, time, date_duration, time_duration, date_period, time_period 等
  • 支持无穷大 - 正无穷大、负无穷大
  • 时间日期范围的迭代器
  • 尽可能将日期和时间实现分离
计算 为高效时间计算提供基础
  • 日期之间的天数
  • 时间时长
  • 日期和时间组合的时长
表示灵活性 提供最大的可重用性和灵活性
  • 基于特性的自定义内部表示,以控制大小与分辨率
  • 允许使用不同的纪元和分辨率(例如:秒与微秒,日期从 2000 年开始与日期从 1700 年开始)
  • 配置独特日历表示(格里高利历 + 其他)的选项
  • 使用儒略日和它与格里高利/儒略日历日期之间的转换
  • 允许灵活调整,包括闰秒
日期计算 提供日期计算工具
  • 为计算复杂的事件规范(如节假日)提供基础
  • 日历到日历的转换
  • 提供扩展到新日历系统的能力
时间计算 提供用于时间操作的具体类
  • 提供处理跨时区问题的能力
  • 提供夏令时(日光节省时间)的调整
时钟接口 提供用于检索当前时间的类
  • 访问网络/高分辨率时间源
  • 检索当前日期时间信息以填充类
I/O 接口 提供时间输入和输出,包括:
  • 多语言支持
  • 提供符合 ISO8601 的时间格式
  • 使用 I/O 格式进行不同的本地行为

权衡:稳定性、可预测性和近似值

不可避免的权衡

库尽最大努力提供用户想要的一切,但存在一些固有的限制,这些限制限制了任何时间库都能做什么。具体来说,用户必须在任何特定应用程序中选择以下三项功能中的两项:

  • 与实际时钟时间精确一致
  • 准确的数学计算,例如时长计算
  • 处理未来时间点的能力

一些库可能隐式承诺提供所有这三项,但如果您实际上测试它们,一次只能实现两项。这种限制不是任何特定库的设计或实现中的缺陷;相反,它是不同时间系统根据国际标准定义方式的结果。让我们看看这三种情况:

如果您希望与实际时钟时间精确一致,您必须使用 UTC 或本地时间。如果您通过从一个 UTC 时间减去另一个 UTC 时间来计算时长,并且您希望答案精确到秒,那么这两个时间点不能离未来太远,因为闰秒会影响计数,但只有在大约 6 个月前才能确定。对于本地时间,未来的时长计算可能会相差一个小时,因为立法者可以并且确实会随意更改 DST 规则。

如果您希望处理未来的实际时钟时间,那么在一般情况下,您将无法计算精确的时长,原因与上面相同。

如果您希望对未来的时间进行准确计算,您将不得不使用 TAI 或等效项,但 TAI 到 UTC 或本地时间的映射取决于闰秒,因此您将无法与实际时钟时间精确一致。

稳定性、可预测性和近似值

这里有一些底层理论有助于解释正在发生的事情。请记住,时间类型,与任何抽象数据类型(ADT)一样,是一组值以及在这些值上的操作。

稳定性

如果一个类型的值的位模式不会随时间改变,那么这个类型的表示就是稳定的。表示不稳定的类型不太可能对任何人有用,因此我们将坚持要求任何时间库都只使用稳定的表示。

如果一个类型上的操作,将其应用于特定操作数的结果不随时间改变,那么这个操作就是稳定的

可预测性

集合通常分为两类:定义明确和定义不明确。由于类型是一个集合,我们可以扩展这些定义来涵盖类型。对于任何类型 T,必须有一个谓词is_member( x ),它决定值 x 是否为类型 T 的成员。此谓词必须返回true, false,dont_know

如果对于所有 x,is_member( x ) 都返回 true 或 false,我们称集合 T 是定义明确的

如果对于任何 x,is_member( x ) 都返回 dont_know,我们称集合 T 是定义不明确的

这些是数学中通常使用的规则。然而,由于时间类型的特殊特性,将其细化并创建第三类是有用的,如下所示:

对于任何时间类型 T,必须有一个谓词is_member( x, t ),它确定值 x 是否为 T 的成员。参数 t 代表评估谓词的时间。对于每个 xi,必须有一个时间 ti 和一个值 v,使得:

  • v = true 或 v = false,并且
  • 对于所有 t < ti,is_member( xi, t ) 都返回 dont_know,并且
  • 对于所有 t >= ti,is_member( xi, t ) 都返回 v。

因此,ti 是我们“知道”xi 是否为 T 成员的时间。现在我们可以定义三类时间类型:

如果对于所有 xi,ti = negative infinity,我们称类型 T 是可预测的

如果对于某些 xi,ti = positive infinity,我们称类型 T 是格式不正确的。

否则,我们称类型 T 是不可预测的(这意味着对于某些 xi,ti 是有限的)。

格式不正确的集合没有实际用途,因此我们不再讨论它们。通俗地说,上面的内容只是说,一个可预测类型的所有值都是预先已知的,但一个不可预测类型的一些值直到某个特定时间才知道。

操作的稳定性

可预测类型具有几个重要属性:

  • 其元素到一组连续整数之间存在一个保序映射,并且
  • 其值的时长运算是稳定的。

这实际效果是,时长计算可以用简单的整数减法实现。可预测类型的示例包括 TAI 时间点和格里高利日期。

不可预测类型具有完全相反的属性:

  • 其元素到一组连续整数之间不存在保序映射,并且
  • 其值的时长运算不稳定。

不可预测类型的示例包括 UTC 时间点和本地时间点。

我们可以进一步细化,说不可预测类型中的一个范围可以被预测,并且完全在该范围内的值上执行的操作将是稳定的。例如,UTC 时间点从 1970-01-01 到现在的范围是可预测的,因此在该范围内的时长计算将是稳定的。

近似值

这些限制是有问题的,因为像 UTC 和本地时间这样重要的时间类型实际上是不可预测的,因此对它们的操作有时是不稳定的。然而,实际上我们经常希望执行这类操作,例如计算未来两个本地时间点之间的时长。

库能做的最好的就是提供一个近似值,这通常是可能的,并且对于大多数目的来说已经足够好。当然,文档必须说明何时答案是近似的(因此不稳定)以及误差可能有多大。在许多方面,使用不可预测集合进行计算类似于使用浮点数,其中结果预计只能是近似正确的。使用可预测集合进行计算则类似于使用整数,其中结果预计是精确的。

对于需要精确答案或无法容忍不稳定的情况,用户必须能够指定这一点,然后如果用户请求一个无法提供精确、稳定答案的计算,库应该抛出异常。

术语

以下是与日期时间域相关的一些术语。

时间类型的分类

  • 时间点 -- 时间连续体中的一个位置的指示符。类似于标尺上的数字。
  • 时间长度 -- 未附着在时间连续体上任何点上的时间长度。
  • 时间间隔 -- 附着在时间连续体上特定点上的时间长度。

其他术语

  • 精度 -- 误差的度量,时钟读数与真实时间之间的差异。
  • 日历系统 -- 用于标记具有日级别分辨率的时间点的系统。
  • 时钟设备 -- 一个软件组件(关联到某种硬件),它根据日历或时钟系统提供当前日期或时间。
  • 精确度 -- 时钟可重复性的度量。
  • 分辨率 -- 指定时钟/日历系统或时间类型可表示的最小时长(例如:1 秒、1 世纪)。
  • 稳定性 -- 一个类(class)的属性,表明与特定(抽象)值相关联的底层表示(实现)永远不会改变。
  • 时间系统 -- 用于标记具有比日级别更高分辨率的时间点的系统。

一些标准的日期时间术语

  • 纪元 -- 日历或时钟系统的开始时间点。
  • DST -- 夏令时 - 在某些地区夏季进行的本地时间调整,以将日光时钟时间向前拨。
  • 时区 -- 地球上一个区域,其“本地时间”由 DST 规则和 UT 偏移定义。
  • UTC 时间 -- 协调世界时 - 在零经度测量的民用时间系统。通过使用闰秒来保持与地球自转的同步。也称为 Zulu 时间。取代了类似的系统 Greenwich Mean Time(格林威治标准时间)。更多信息请参见http://aa.usno.navy.mil/faq/docs/UT.html
  • TAI 时间 -- 原子钟在世界各地以 0.1 微秒的分辨率测量的、高精度单调(需要更好的词)的时间系统。不与地球自转同步。更多信息请参见http://www.bipm.fr/enus/5_Scientific/c_time/time_server.html

一些更具实验性的

  • 本地时间 -- 在特定地理位置测量的时间。
  • 时间标签 -- 一个元组,相对于日历或时钟系统,它完全或部分指定了一个特定的日期时间。这是年-月-日表示。
  • 调整时间长度 -- 一个表示随时间变化的物理时长的时长。例如,1 个月时长通常不是固定天数,它取决于测量它的日期来确定实际长度。

这些是设计相关的术语

  • 生成函数 -- 一个基于一个或多个参数生成特定时间点、长度或间隔集的函数。

参考文献

该库的设计目前正在通过 Wiki 和电子邮件讨论进行演变。您可以在以下位置找到更多信息:Boost Wiki GDTL 起始页

日期日历参考文献

时间

其他 C/C++ 库

JAVA 日期与时间库快速参考

脚本语言库

相关的商业和虚构页面

分辨率、精确度和准确性

构建-编译器信息

概述 -- 编译选项 -- 编译器/可移植性说明 -- 目录结构 -- 所需的 Boost 库

概述

该库有几个函数需要创建库文件(主要是 to_string, from_string 函数)。大多数库用户可以在构建库的情况下有效使用该库,只需包含所需的头文件即可。如果需要库,构建目录中的 Jamfile 将生成一个“静态”库(libboost_date_time)和一个包含这些函数的“动态/共享”库(boost_date_time)。请注意,在 Windows 上,在不使用库的情况下使用该库可能需要使用 BOOST_DATE_TIME_NO_LIB 标志进行编译。

编译选项

默认情况下,posix_time 系统在内部使用一个 64 位整数来提供微秒级分辨率。作为替代,可以使用一个 64 位整数和一个 32 位整数(96 位分辨率)的组合来提供纳秒级分辨率。默认实现可能为许多不需要纳秒分辨率的应用程序提供更好的性能和更紧凑的内存使用。

要使用备用分辨率(96 位纳秒),必须在库用户的项目文件中(即 Makefile, Jamfile 等)定义变量 BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG。格里高利历系统不使用此宏,因此在构建库时没有效果。

从 1.33 版本开始,date_time 库引入了一个新的 IO 流系统。一些编译器无法利用这个新系统。对于这些编译器,仍然可以使用较早的(“遗留”)IO 系统。不受支持的编译器会自动选择遗留系统,但用户可以通过定义 USE_DATE_TIME_PRE_1_33_FACET_IO 来强制使用遗留系统。

为了方便起见,date_time 提供了一些附加的时长类型。使用这些类型可能会由于月末吸附行为而产生意外结果(有关完整详细信息和示例,请参见操作可逆性陷阱)。默认情况下启用这些类型。要禁用这些类型,只需在您的项目文件中取消定义 BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES

另一个便利之处是 dateptime 的默认构造函数。默认情况下启用这些构造函数。要禁用它们,只需在您的项目文件中定义 DATE_TIME_NO_DEFAULT_CONSTRUCTOR

编译器/可移植性说明

Boost Date-Time 库已在许多编译器和平台上构建和测试过。但是,一些编译器和标准库存在问题。虽然其中一些问题可以规避,但其他问题很难规避。以下编译器被认为完全支持库的所有方面:

  • Codewarrior 9.4 Windows
  • GCC 3.2 - 3.4, 4.x on Linux
  • GCC 3.3, 4.x on Darwin
  • GCC 3.3 - 3.4, 4.x on Solaris
  • GCC 3.3, 4.x on HP-UX
  • QCC 3.3.5 on QNX
  • MSVC 7.1 Windows
  • Intel 8.1-9.x Linux and Windows

不幸的是,VC8 编译器在日期时间代码方面存在一些问题。最严重的问题是 VC8 标准库 basic_stream 代码中引入了内存泄漏。Date-time 代码已进行了更改以尽可能避免此问题,但如果您使用的是遗留 IO 选项(VC8 的默认选项不是),则该问题仍然可能发生。更多详情请参见邮件列表存档

除了上述问题,VC8 的某些版本还限制了 std::tm 结构中允许值的范围为正值。这是 VC8 中新增的限制。效果是 1900 年之前的日期会导致异常。不幸的是,对此问题没有简单的解决方法。请注意,VC8 编译器的新 64 位版本似乎没有此限制。

这些编译器支持库的所有方面,但 wstring/wstream 输出除外。

  • MinGW 3.2, 3.4, 3.5 *
  • GCC 3.2 (cygwin) *

特别是,对标准 locale 的支持不足限制了库支持 iostream 输入输出的能力。对于这些编译器,提供了一组更有限的基于字符串的输入输出。一些具有此限制的编译器/标准库包括:

  • Borland 5.6

一些旧编译器的官方支持现已停止。包括:

  • GCC 2.9x
  • Borland 5.1.1
  • MSVC 7.0 and 6 SP5

Visual Studio & STLPort

Visual Studio (7.0 & 7.1) 和 STLPort 存在一个已知问题。构建错误通常会引用类型问题或“无可用转换”,并尝试使用 wchar_t 实例化模板。STLPort 的默认构建不支持 wchar_t。此问题有两种可能的解决方法。最简单的方法是用户可以构建不带宽流/字符串等的 date_time。另一种方法是使用 wchar_t 支持重新构建 STLPort。

要构建不带宽流/字符串等的 date_time,请从 $BOOST_ROOT 执行以下命令:

bjam -a "-sTOOLS=vc-7_1-stlport" "-sSTLPORT_PATH=..." \
     "-sBUILD=<define>BOOST_NO_STD_WSTRING"           \
     --stagedir=... --with-date_time stage

(用正确的构建系统路径替换省略号,并根据需要调整 TOOLS 为正确的工具集)

使用 wchar_t 支持重新构建 STLPort 涉及在 STLPort makefile 中放置 /Zc:wchar_t。然后应从 $BOOST_ROOT 使用以下命令构建 Date_time:

bjam -a "-sTOOLS=vc-7_1-stlport" "-sSTLPORT_PATH=..." \
     "-sBUILD=&native-wchar_t>on"                     \
     --stagedir=... --with-date_time stage

(用正确的构建系统路径替换省略号,并根据需要调整 TOOLS 为正确的工具集)

目录结构

目录树具有以下结构:

/boost/date_time                   -- common headers and template code
/boost/date_time/gregorian         -- Gregorian date system header files
/boost/date_time/posix_time        -- Posix time system headers
/boost/date_time/local_time        -- Local time system headers
/libs/date_time/build              -- build files and output directory
/libs/date_time/test               -- test battery for generic code
/libs/date_time/test/gregorian     -- test battery for the Gregorian system
/libs/date_time/test/posix_time    -- test battery for the posix_time system
/libs/date_time/test/local_time    -- test battery for the local_time system
/libs/date_time/example/gregorian  -- example programs for dates
/libs/date_time/example/posix_time -- time example programs
/libs/date_time/example/local_time -- nifty example programs
/libs/date_time/src/gregorian      -- cpp files for libboost_date_time
/libs/date_time/src/posix_time     -- empty (one file, but no source code...)

所需的 Boost 库

date-time 的各个部分依赖于其他 boost 库。这些包括:

因此,这些库需要安装。

测试

库在

      libs/date_time/test
      libs/date_time/test/gregorian
      libs/date_time/test/posix_time
      libs/date_time/test/local_time
    

目录中提供了大量的测试。构建和执行这些测试可确保安装正确且库正常运行。此外,这些测试有助于移植到新编译器。最后,测试提供了许多未在用法示例中明确描述的函数的示例。

变更历史

从 Boost 1.73 到 1.74 的变更

类型 描述
Bug 修复 修复 constrained_value::assign 为 constexpr,以便 ptime 和 date 的构造为 constexpr。请参见:pull 161pull 161
Bug 修复 在 Clang 上抑制 MSVC CRT 弃用警告。请参见:pull 160

从 Boost 1.72 到 1.73 的变更

类型 描述
增强 使 date_time 全部内联。用户不再需要为任何库函数链接库。请注意,为了向后兼容,会维护一个空的存根库。解决:(github issue #134) 和 (github issue #85)。删除链接库以解决链接/可见性问题。
增强 在 C++14 及以上版本中已添加对 constexpr 的支持。例如: constexpr microseconds ms(1000); static_assert(ms.total_microseconds() == 1000, "constexpr total_microseconds"); github issue #123)。
增强 C++20 在 clang 10 下的歧义比较运算符警告(github issue #132)。
清理 弃用了对遗留 IO 和 USE_DATE_TIME_PRE_1_33_FACET_IO 宏的支持(github issue #61)。
Bug 修复 文档澄清了 gettimeofday、day_number 和 from_iso_extended_string。 github issue #127 github issue #125,和 github issue #116

从 Boost 1.41 到 1.44 的变更(date_time 1.08 到 1.09)

类型 描述
Bug 修复 "%T" 和 "%R" 格式说明符现在由库处理,而不是底层的标准格式。这修复了占位符不受格式支持的情况(#3876)。

从 Boost 1.40 到 1.41 的变更(date_time 1.07 到 1.08)

类型 描述
更改 时间时长的默认格式现在是 "%-%O:%M:%S%F",而不是之前使用的 "%-%H:%M:%S%F"。为了保留旧的行为,在构建时间 IO 格式时必须显式指定格式字符串(#1861)。
Bug 修复 在 64 位平台上,格里高利日期现在内部使用 32 位整数类型(#3308)。
Bug 修复 调整了 UTC 时区偏移边界,以允许偏移量达到 +14 小时(#2213)。

从 Boost 1.38 到 1.40 的变更(date_time 1.06 到 1.07)

类型 描述
Bug 修复 小型 Bug 修复(#2809#2824#3015#3105 及其他)。

从 Boost 1.34 到 1.38 的变更(date_time 1.05 到 1.06)

类型 描述
功能 增加了对格式化和读取超过 24 小时的时间时长的支持。在格式字符串中,使用新的格式化符 %O 来表示这种长时长。旧的 %H 格式说明符因此仅限于表示适合两个字符的时长,以便保留读取 ISO 格式时长的支持。如果检测到 %H 格式说明符与更长时长的使用,则结果未定义(调试版本中会发出断言)。
Bug 修复 增加了对 GCC 4.3 的支持。解决了几个编译问题,并处理了编译器警告。
Bug 修复 local_time_period 类添加了缺失的流运算符。
Bug 修复 在不同地方添加了几个缺失的 include。一些在某些配置中不需要的 include 被条件化。
Bug 修复 解决了由于未通过 ADL 找到 gregorian::date_duration 的流运算符而导致的编译问题。该类型现在实际上是类而不是 date_time::date_duration 模板的 typedef。对 gregorian::weeks 也进行了类似更改。
Bug 修复 添加了一个拼写正确的 date_time::hundredth 时间分辨率枚举值。旧的 date_time::hundreth 被视为已弃用,将在未来版本中删除。
Bug 修复 修复了 format_date_parser.hpp 中的编译错误,原因是使用了不正确的流类型。
Bug 修复 在 Windows 平台,windows.h 的包含已变为可选。仅当定义了 BOOST_USE_WINDOWS_H 宏时才使用此头文件。否则(默认情况下),库使用此头文件中的符号的内部定义。
Bug 修复 在 Windows 平台上,如果传递给 from_ftime 函数的 FILETIME 包含 1970 年 1 月 1 日之前的日期,则该函数可能返回不正确的时间。
Bug 修复 修复了 gregorian::special_value_from_string 中可能发生的崩溃问题,如果字符串不是有效的特殊值。
Bug 修复 从公共包含目录中删除了 testfrmwk.hpp 文件。此文件是库测试的内部文件,未被记录。
Bug 修复 修复了 filetime_functions.hpp 中缺失的 include(#2688)。
Bug 修复 修复了代码中解引用字符串末尾迭代器的问题,这可能导致 MSVC 崩溃(#2698)。

从 Boost 1.33 到 1.34 的变更(date_time 1.04 到 1.05)

类型 描述
功能 已更新 date_time_zonespec.csv 文件中的数据,以反映 2007 年新的美国/加拿大夏令时规则。如果您升级到新文件,请注意,该库仅在当前/未来日期转换时提供正确答案。因此,如果您转换的是往年的日期,答案将反映当前时区规则而不是过去的规则。该库目前不支持历史时区规则。
功能 其他两个 DST 计算功能也已更新以反映新的美国/加拿大时区规则。这是 boost::date_time::us_dst_rules 和 dst_calc_engine。虽然 us_dst_rules 已被正式弃用,但 Graham Bennett 提供的一个补丁已应用,该补丁允许此类正确处理历史和未来的日期。dst_calc_engine 也已更新,可以处理历史和未来的时间。这使得各种 local_adjustor 类能够正确工作。使用带有自定义 DST 特性类的 dst_calc_engine 时,接口发生了更改。特性类的签名更改为在大多数方法(如 end_month)中接受一个“year”参数。此外,特性类还需要 2 个新函数:static date_type local_dst_start_day(year_type year)static date_type local_dst_end_day(year_type year)。实现者应参考 date_time/local_timezone_defs.hpp 中的示例。
Bug 修复 修复了澳大利亚的 DST 特性(sf# 1672139),将 DST 结束时间设置为凌晨 3:00 而不是凌晨 2:00。
Bug 修复 修复了由于 IO 代码可能导致的链接错误问题。
Bug 修复 修改了 greg_serialize.hpp 和 time_serialize.hpp 中的序列化代码,以消除因未使用版本和文件版本变量而产生的警告。感谢 Caleb Epstein 提供补丁建议。
Bug 修复 修复了在 FreeBSD 上使用 GCC 且 LANG 环境变量设置为俄语时出现的回归错误 -- 将解析器更改为使用经典 locale 而不是空白 locale。
Bug 修复 针对跟踪器 issue 1178092 的更改 -- 更改了 convert_to_lower 以使 local 成为 const static,从而加速解析。
Bug 修复 Ulrich Eckhardt 的补丁,用于修复对 EVC++ 4 的支持。
功能 尽可能减少 basic_stringstream 的使用,以规避 VC8 标准库中的一个 Bug。更多信息请参见邮件列表存档

从 Boost 1.32 到 1.33 的变更(date_time 1.03 到 1.04)

类型 描述
Bug 修复 当开始点和结束点相同或连续时,周期长度的计算不正确。已修正的行为是,当结束点和开始点相等,或创建的周期时长为零时,现在返回长度为零。开始点和结束点连续的周期将返回长度为一。
Bug 修复 Time_input_facet 缺少设置 ISO 格式的函数。它也未能解析不使用分隔符的时间值(%H%M%S)。这两个 Bug 都已得到纠正。
功能 ptime_facet 和 ptime_input_facet 的初步名称已更改为 time_facet 和 time_input_facet。ptime_* 版本已被完全删除。
功能 from_iso_string 函数未能解析小数位数。我们添加了代码,可以在输入具有比编译库精度更多或更少数字时正确解析。仅带小数点的 Ptimes 也能正确解析。
Bug 修复 新 IO 中的解析机制会在匹配后消耗下一个字符。当尝试解析开始点具有特殊值的周期时,会出现此 Bug。
Bug 修复 新 IO 系统未能提供用户“打开”流中异常的能力。解析失败时也没有设置 failbit。这两个问题都已修复。
Bug 修复 通过 from_*_string 函数解析特殊值已得到修复。这也影响了库序列化特殊值的能力。Time_duration 现在序列化为字符串或单独字段(取决于 is_special())。
Bug 修复 以前,partial_date 的输出流会显示天数为一位或两位数字(例如 '1' 或 '12')。这已得到纠正,始终显示为两位数字(例如 '01')。
功能 与本地时间管理相关的主要新功能。这包括引入一系列新类来表示时区和本地时间(有关详细信息,请参见Date Time Local Time)。
功能 输入和输出格式已重写,以支持基于格式的格式重定义(有关详细信息,请参见Date Time IO)。
功能 添加了函数以方便 tm 结构与 dateptimetime_durationlocal_date_time 之间的转换。还提供了将 FILETIMEtime_t 转换为 ptime 的函数。有关详细信息,请参见各个部分。
功能 microsec_time_clock 中添加了一个 universal_time 函数(有关此函数的完整详细信息,请参见此处)。
功能 添加了函数以方便 tm 结构与 dateptimetime_durationlocal_date_time 之间的转换。还提供了将 FILETIMEtime_t 转换为 ptime 的函数。有关详细信息,请参见各个部分。
功能 microsec_time_clock 中添加了一个 universal_time 函数(有关此函数的完整详细信息,请参见此处)。
功能 当定义 BOOST_HAS_THREADS 时,Date-time 现在会在支持的平台上使用可重入 POSIX 函数。
Bug 修复 修复了序列化代码中的一个 Bug,其中 ptime、time_duration 的特殊值(非日期时间、无穷大等)无法从存档正确读取。输出序列化代码写入了 time_duration.seconds() 等子字段,这些字段对于特殊值无效,因此是未定义的。因此,在读取时,这些值可能导致奇怪的行为,包括构造时抛出异常。
Bug 修复 修复了各种平台/编译器生成的多个警告。
Bug 修复 使用超出 00:00 至 23:59:59.9... 范围的时长构造 ptime 现在会调整日期和时间,以使时长落在该范围内(例如 ptime(date(2005,2,1), hours(-5)) -> "2005-Jan-31 19:00:00" & ptime(date(2005,2,1), hours(35)) -> "2005-Feb-02 11:00:00")。
Bug 修复 时间解析现在可以正确处理过多的小数秒位数。前导零被删除("000100" -> 100 frac_sec),多余的数字会在适当位置被截断("123456789876" -> 123456 或 123456789,取决于库编译的精度)。
Bug 修复 boost::serialization 接口的更改破坏了 date_time 的序列化兼容性。用户必须提供一个函数来确保 date_time 对象在序列化前是 const 的。该函数应类似于:
template<class archive_type, class temporal_type>
void save_to(archive_type& ar,
             const temporal_type& tt)
{
  ar << tt;
}
Bug 修复 使用已弃用的 boost::tokenizer 接口已更新为当前接口。这修复了某些旧编译器上的编译错误。
Bug 修复 将遗留 IO 系统中的格式化器模板化以接受 char 类型。还删除了对 boost::lexical_cast 的调用。

从 Boost 1.31 到 1.32 的变更(date_time 1.02 到 1.03)

类型 描述
Bug 修复 已纠正 year_functor 的月末吸附行为。以前,从 2000-Feb-28(闰年且非月末)开始,迭代到下一个闰年会得到 2004-Feb-29,而不是 2004-Feb-28。该行为已纠正,以产生正确的 2004-Feb-28 结果。感谢 Bart Garst 进行此更改。
功能 用于从 FILETIME 结构创建 ptime 对象的自由函数。此函数仅在定义了 BOOST_HAS_FTIME 的平台上可用。
功能 微秒时钟现在在大多数 Windows 编译器和 Unix 上可用。
功能 现在可以使用 boost::serialization 库来处理 date_time 的大多数类。可序列化的类是:date_generator 类、date、days、date_period、greg_month、greg_weekday、greg_day、ptime、time_duration 和 time_period。感谢 Bart Garst 进行此更改。
功能 添加了函数,用于将日期和时间类转换为 wstring。该库现在为编译器支持 wstrings 的情况提供 to_*_wstring 和 to_*_string 函数,用于:simple、iso、iso_extended 和 sql 格式的日期。感谢 Bart Garst 进行此更改。
功能 周期类现在可以正确处理零长度和 NULL 周期。NULL 周期是长度为负的周期。感谢 Frank Wolf 和 Bart Garst 进行此更改。
功能 向 gregorian::date 添加了 end_of_month 函数,以返回日期表示的当前月份的最后一天。对于 not_a_date_time 或 infinities,结果未定义。
Bug 修复 删除了库中对 BOOST_NO_CWCHAR 宏的不正确使用。
功能 为一些日期类添加了新名称。原始名称仍然有效,但将来可能会被弃用。更改包括:
date_duration 现为 days
nth_kday_of_month 现为 nth_day_of_the_week_in_month
first_kday_of_month 现为 first_day_of_the_week_in_month
last_kday_of_month 现为 last_day_of_the_week_in_month
first_kday_after 现为 first_day_of_the_week_after
first_kday_before 现为 first_day_of_the_week_before
功能 为日期生成器添加了自由函数。函数包括:days_until_weekday, days_before_weekday, next_weekday, 和 previous_weekday。
days days_until_weekday(date, greg_weekday);
days days_before_weekday(date, greg_weekday);
date next_weekday(date, greg_weekday);
date previous_weekday(date, greg_weekday);
感谢 Bart Garst 进行此更改。
功能 添加了新的实验性时长类型,用于月份、年份和周。这些类还提供了用于日期和时间类的数学运算符。请注意,将月份或年份添加到 28 日之后的日期或时间可能会显示非正常的数学特性。这是计算中使用的“月末吸附”的结果。最后一个示例说明了该问题。
months m(12);
years y(1);
m == y; // true
days d(7);
weeks w(1);
d == w; // true
ptime t(...);
t += months(3);
date d(2004,Jan,30);
d += months(1); //2004-Feb-29
d -= months(1); //2004-Jan-29
这些类型尚未实现输入流。感谢 Bart Garst 进行此更改。
功能 将日期生成器的统一基类引入 gregorian 命名空间。请参见打印节假日示例
功能 为 date 和 ptime 添加了构造函数,允许默认构造(两者)和特殊值构造(ptime,两者现在都支持)。默认构造函数将对象初始化为 not_a_date_time (NADT)。
ptime p_nadt(not_a_date_time);
ptime p_posinf(pos_infin);
ptime p; // p == NADT
date d;  // d == NADT
感谢 Bart Garst 进行此更改。
功能 输出流现在支持宽流输出,适用于支持宽流的编译器/标准库组合。这允许像以下代码:
std::wstringstream wss;
date d(2003,Aug,21);
wss << d;
感谢 Bart Garst 进行此更改。
功能 日期和时间类型的输入流现在同时支持宽流和窄流。
date d(not_a_date_time);
std::stringstream ss("2000-FEB-29");
ss >> d; //Feb 29th, 2000
std::wstringstream ws("2000-FEB-29");
ws >> d; //Feb 29th, 2000
感谢 Bart Garst 进行此更改。
Bug 修复 修复了 duration_from_string() 中的 Bug,该 Bug 导致格式化的小数位数少于全量的字符串创建了不正确的时间时长。对于微秒分辨率的时间时长,字符串 "1:01:01.010" 创建的时间时长为 01:01:01.000010,而不是 01:01:01.010000。
Bug 修复 修复了 gregorian::date 和 posix_time::ptime 在使用 min_date_time 或 max_date_time 构造时的特殊值构造函数。这些构造函数生成的值不正确。

从 Boost 1.30 到 1.31 的变更(date_time 1.01 到 1.02)

类型 描述
Bug 修复 构建配置已更新,以便使用 MSVC 编译器生成 dll、静态库和动态可链接库文件。有关更多详细信息,请参见构建/编译器信息
Bug 修复 Time_duration from_string 现在可以正确地从负值构造。(例如 "-0:39:00.000")。代码由 Bart Garst 提供。
Bug 修复 修复了在警告级别 4 下编译时出现的许多 MSVC 编译器警告。
功能 为日期和时间迭代器添加了前缀递减运算符(--)。有关更多详细信息,请参见时间迭代器日期迭代器。代码由 Bart Garst 提供。
功能 为 date_duration、time_duration 和 time 类添加了 special_values 功能。代码由 Bart Garst 提供。
Bug 修复 修复了 time_duration_traits 计算 Bug,该 Bug 导致时间时长被限制在 32 位范围内,即使 64 位可用。感谢 Joe de Guzman 发现了这个问题。
Bug 修复 为时长类型(例如 date_duration, time_duration)提供了附加运算符。包括整数除法,并修复了允许 +=, -= 运算符。感谢 Bart Garst 编写此代码。此外,计算的文档已得到改进。
Bug 修复 在 boost::gregorian gregorian_types.hpp 中为各种日期生成器函数类添加了 typedef。
功能 添加了 from_time_t 函数,用于将 time_t 转换为 ptime。
功能 为合并周期添加了一个 span 函数。请参见日期周期时间周期文档。
功能 向 time_duration 添加了一个函数,用于获取时长中的总秒数,并截断任何小数秒。此外,还添加了其他分辨率以方便转换。例如:
seconds(1).total_milliseconds() == 1000
seconds(1).total_microseconds() == 1000000
hours(1).total_milliseconds() == 3600*1000 //3600 sec/hour
seconds(1).total_nanoseconds() == 1000000000
功能 为日期生成器类(partial_date, first_kday_after, first_kday_before, 等)添加了输出流运算符。感谢 Bart Garst 完成此工作。
功能 为时长添加了一元运算符(-),用于反转时间时长的符号。例如:
time_duration td(5,0,0); //5 hours
td = -td; //-5 hours
感谢 Bart Garst 完成此工作。
功能 支持解析带有“月份名称”的字符串。因此,从字符串创建日期对象现在接受多种格式("2003-10-31"、"2003-Oct-31" 和 "2003-October-31")。因此,date d = from_simple_string("2003-Feb-27") 现在是允许的。无效的月份名称字符串(from_simple_string("2003-SomeBogusMonthName-27"))将导致 bad_month 异常。在大多数编译器上,字符串比较是不区分大小写的。感谢 Bart Garst 完成此工作。
功能 除了支持月份名称或数字外,还添加了函数来从多顺序日期字符串创建日期对象。例如:"January-21-2002"、"2002-Jan-21" 和 "21-Jan-2003"。有关更多详细信息,请参见日期类
Bug 修复 各种文档修复。感谢 Bart Garst 的更新。

从 Boost 1.29 到 1.30 的变更(date_time 1.00 到 1.01)

注意:partial_date 类的接口(参见date_algorithms)已更改。构造参数的顺序已更改,这会导致某些代码执行失败。此更改是为了促进更通用的本地时间调整代码。因此,与其指定 partial_date pd(Dec,25),代码需要更改为 partial_date pd(25, Dec);

类型 描述
Bug 修复 添加了新的实验性夏令时计算功能。这允许基于特性的 DST 规则规范。
功能 向 gregorian 日期类添加了计算儒略日和修正儒略日的新接口。请参见boost::gregorian::date
功能 向 boost::gregorian::date 添加了计算 ISO 8601 周数的新接口。
功能 添加了一个 ISO 8601 时间日期格式(例如 YYYYMMDDTHHHMMSS)的解析函数。有关更多信息,请参见Class ptime
功能 向 period 模板添加了一个 length 函数,以便 date_period 和 time_period 现在都支持此函数。
Bug 修复 将 Jamfiles 分割,以便 libs/date_time/build/Jamfile 仅构建库,而 /libs/date_time/libs/test/Jamfile 运行测试。
Bug 修复 修复了许多小文档问题。
Bug 修复 删除了导致链接错误的 DATE_TIME_INLINE 宏。使用该库的项目不再需要此宏。
Bug 修复 为 gregorian_types.hpp 中的 year_iterator 添加了缺失的 typedef。
Bug 修复 修复了 gregorian ostream 运算符的问题,该问题阻止了宽流的使用。
Bug 修复 收紧了日期错误处理,因此 date(2002, 2, 29) 将抛出 bad_day_of_month 异常。以前,日期会被错误地构造。由 sourceforge bug: 628054 等报告。

致谢

许多人对该库的发展做出了贡献。特别是 Hugo Duncan 和 Joel de Guzman 协助移植到各种编译器。对于概念和设计的初始开发,Corwin Joy 和 Michael Kenniston 值得特别感谢。也非常感谢 Michael 撰写了文档的理论和权衡部分。Dave Zumbro 提供了最初的灵感和明智的建议。非常感谢 boost 的审稿人和用户,包括:William Seymour, Kjell Elster, Beman Dawes, Gary Powell, Andrew Maclean, William Kempf, Peter Dimov, Chris Little, David Moore, Darin Adler, Gennadiy Rozental, Joachim Achtzehnter, Paul Bristow, Jan Langer, Mark Rodgers, Glen Knowles, Matthew Denman, and George Heintzelman。


PrevUpHomeNext