【BOOST C++ 10 时间数据】(3)本地不独立时间(11-11)

发布于:2022-11-09 ⋅ 阅读:(9) ⋅ 点赞:(0) ⋅ 评论:(0)

一、位置相关时间

        与上一节中介绍的与位置无关的时间不同,与位置相关的时间考虑了时区。 Boost.DateTime 提供类 boost::local_time::local_date_time,定义在 boost/date_time/local_time/local_time.hpp 中。此类使用 boost::local_time::posix_time_zone 存储时区相关数据。

二、示例代码

示例 36.17。使用 boost::local_time::local_date_time

#include <boost/date_time/local_time/local_time.hpp>
#include <iostream>

using namespace boost::local_time;
using namespace boost::posix_time;
using namespace boost::gregorian;

int main()
{
  time_zone_ptr tz{new posix_time_zone{"CET+1"}};
  ptime pt{date{2014, 5, 12}, time_duration{12, 0, 0}};
  local_date_time dt{pt, tz};
  std::cout << dt.utc_time() << '\n';
  std::cout << dt << '\n';
  std::cout << dt.local_time() << '\n';
  std::cout << dt.zone_name() << '\n';
}

        boost::local_time::local_date_time 的构造函数期望它的第一个参数是 boost::posix_time::ptime 类型的对象,它的第二个参数是 boost::local_time::time_zone_ptr 类型的对象。 boost::local_time::time_zone_ptr 是 boost::shared_ptr<boost::local_time::time_zone> 的类型定义。类型定义基于 boost::local_time::time_zone,而不是 boost::local_time::posix_time_zone。这很好,因为 boost::local_time::posix_time_zone 是从 boost::local_time::time_zone 派生的。这使得使用用户定义的时区类型扩展 Boost.DateTime 成为可能。

        没有传递 boost::local_time::posix_time_zone 类型的对象。相反,会传递一个引用该对象的智能指针。这允许 boost::local_time::local_date_time 类型的多个对象共享时区数据。当最后一个对象被销毁时,代表时区的对象将自动释放。

        要创建 boost::local_time::posix_time_zone 类型的对象,将描述时区的字符串作为唯一参数传递给构造函数。示例 36.17 将中欧指定为时区(CET 是中欧时间的缩写)。由于 CET 比 UTC 早一小时,因此偏差表示为 +1。 Boost.DateTime 无法解释时区的缩写,因此不知道 CET 的含义。因此,必须始终以小时为单位提供偏差;如果没有偏差,则使用值 +0。

        程序将字符串 2014-May-12 12:00:00、2014-May-12 13:00:00 CET、2014-May-12 13:00:00 和 CET 写入标准输出流。用于初始化 boost::posix_time::ptime 和 boost::local_time::local_date_time 类型对象的值默认总是与 UTC 时区相关。当 boost::local_time::local_date_time 类型的对象被写入标准输出流或调用成员函数 local_time() 时,以小时为单位的偏差用于计算本地时间。

        示例 36.18。位置相关的时间点和不同的时区

#include <boost/date_time/local_time/local_time.hpp>
#include <iostream>

using namespace boost::local_time;
using namespace boost::posix_time;
using namespace boost::gregorian;

int main()
{
  time_zone_ptr tz{new posix_time_zone{"CET+1"}};

  ptime pt{date{2014, 5, 12}, time_duration{12, 0, 0}};
  local_date_time dt{pt, tz};
  std::cout << dt.local_time() << '\n';

  time_zone_ptr tz2{new posix_time_zone{"EET+2"}};
  std::cout << dt.local_time_in(tz2).local_time() << '\n';
}

        使用 local_time(),时区的偏差得到尊重。为了计算 CET 时间,需要将 1 小时添加到存储在 dt 中的 12 PM 的 UTC 时间,因为 CET 比 UTC 早一小时。这就是示例 36.18 中 local_time() 将 2014-May-12 13:00:00 写入标准输出的原因。

        相反,成员函数 local_time_in() 将存储在 dt 中的时间解释为在作为参数传递的时区中。这意味着 12 PM UTC 等于 2 PM EET,它代表东欧时间,比 UTC 早两个小时。

        最后,Boost.DateTime 提供类 boost::local_time::local_time_period 用于与位置相关的时段。

        示例 36.19。使用 boost::local_time::local_time_period

#include <boost/date_time/local_time/local_time.hpp>
#include <iostream>

using namespace boost::local_time;
using namespace boost::posix_time;
using namespace boost::gregorian;

int main()
{
  time_zone_ptr tz{new posix_time_zone{"CET+0"}};

  ptime pt1{date{2014, 12, 5}, time_duration{12, 0, 0}};
  local_date_time dt1{pt1, tz};

  ptime pt2{date{2014, 12, 5}, time_duration{18, 0, 0}};
  local_date_time dt2{pt2, tz};

  local_time_period tp{dt1, dt2};

  std::cout.setf(std::ios::boolalpha);
  std::cout << tp.contains(dt1) << '\n';
  std::cout << tp.contains(dt2) << '\n';
}

        例 36.19 中 boost::local_time::local_time_period 的构造函数需要两个 boost::local_time::local_date_time 类型的参数。与为周期提供的其他类型一样,代表结束时间的第二个参数不是周期的一部分。借助 contains()、intersection()、merge() 等成员函数,您可以根据 boost::local_time::local_time_period 处理周期。