10.4. 位置相关的时间

和前一节所介绍的位置无关时间不一样,位置相关时间是要考虑时区的。 为此,Boost.DateTime 提供了 boost::local_time::local_date_time 类,它定义于 boost/date_time/local_time/local_time.hpp, 并使用 boost::local_time::posix_time_zone 来保存时区信息。

  1. #include <boost/date_time/local_time/local_time.hpp>
  2. #include <iostream>
  3.  
  4. int main()
  5. {
  6. boost::local_time::time_zone_ptr tz(new boost::local_time::posix_time_zone("CET+1"));
  7. boost::posix_time::ptime pt(boost::gregorian::date(2009, 1, 5), boost::posix_time::time_duration(12, 0, 0));
  8. boost::local_time::local_date_time dt(pt, tz);
  9. std::cout << dt.utc_time() << std::endl;
  10. std::cout << dt << std::endl;
  11. std::cout << dt.local_time() << std::endl;
  12. std::cout << dt.zone_name() << std::endl;
  13. }

boost::local_time::local_date_time 的构造函数要求一个 boost::posix_time::ptime 类型的对象作为其第一个参数,以及一个 boost::local_time::time_zone_ptr 类型的对象作为第二个参数。 后者只不过是 boost::shared_ptr<boost::local_time::posix_time_zone> 的类型定义。 换句话说,并不是传递一个 boost::local_time::posix_time_zone 对象,而是传递一个指向该对象的智能指针。 这样,多个 boost::local_time::local_date_time 类型的对象就可以共享时区信息。 只有当最后一个对象被销毁时,相应的表示时区的对象才会被自动释放。

要创建一个 boost::local_time::posix_time_zone 类型的对象,就要将一个描述该时区的字符串作为单一参数传递给构造函数。 以上例子指定了欧洲中部时区:CET 是欧洲中部时间(Central European Time)的缩写。 由于 CET 比 UTC 早一个小时,所以时差以 +1 表示。 Boost.DateTime 并不能解释时区的缩写,也就不知道 CET 的意思。 所以,必须以小时数给出时差;传入 +0 表示没有时差。

在执行时,该程序将打印 2009-Jan-05 12:00:00, 2009-Jan-05 13:00:00 CET, 2009-Jan-05 13:00:00CET 到标准输出流。 用以初始化 boost::posix_time::ptimeboost::local_time::local_date_time 类型的值缺省总是与 UTC 时区相关的。 只有当一个 boost::local_time::local_date_time 类型的对象被写出至标准输出流时,或者调用 local_time() 方法时,才使用时差来计算本地时间。

  1. #include <boost/date_time/local_time/local_time.hpp>
  2. #include <iostream>
  3.  
  4. int main()
  5. {
  6. boost::local_time::time_zone_ptr tz(new boost::local_time::posix_time_zone("CET+1"));
  7. boost::posix_time::ptime pt(boost::gregorian::date(2009, 1, 5), boost::posix_time::time_duration(12, 0, 0));
  8. boost::local_time::local_date_time dt(pt, tz);
  9. std::cout << dt.local_time() << std::endl;
  10. boost::local_time::time_zone_ptr tz2(new boost::local_time::posix_time_zone("EET+2"));
  11. std::cout << dt.local_time_in(tz2).local_time() << std::endl;
  12. }

通过使用 localtime() 方法,时区的偏差才被考虑进来。 为了计算 CET 时间,需要往保存在 _dt 中的 UTC 时间 12 PM 上加一个小时,因为 CET 比 UTC 早一个小时。 local_time() 会相应地输出 2009-Jan-05 13:00:00 到标准输出流。

相比之下,localtime_in() 方法是在所传入参数的时区内解释保存在 _dt 中的时间。 这意味着 12 PM UTC 相当于 2 PM EET,即东部欧洲时间,它比 UTC 早两个小时。

最后,Boost.DateTime 通过 boost::local_time::local_time_period 类提供了位置相关的时间区间。

  1. #include <boost/date_time/local_time/local_time.hpp>
  2. #include <iostream>
  3.  
  4. int main()
  5. {
  6. boost::local_time::time_zone_ptr tz(new boost::local_time::posix_time_zone("CET+0"));
  7. boost::posix_time::ptime pt1(boost::gregorian::date(2009, 1, 5), boost::posix_time::time_duration(12, 0, 0));
  8. boost::local_time::local_date_time dt1(pt1, tz);
  9. boost::posix_time::ptime pt2(boost::gregorian::date(2009, 1, 5), boost::posix_time::time_duration(18, 0, 0));
  10. boost::local_time::local_date_time dt2(pt2, tz);
  11. boost::local_time::local_time_period tp(dt1, dt2);
  12. std::cout << tp.contains(dt1) << std::endl;
  13. std::cout << tp.contains(dt2) << std::endl;
  14. }

boost::local_time::local_time_period 的构造函数要求两个类型为 boost::local_time::local_date_time 的参数。 和其它类型的时间区间一样,第二个参数所表示的结束时间并不包含在区间之内。 通过如 contains(), intersection(), merge() 以及其它的方法,时间区间可以与其它 boost::local_time::local_time_period 相互操作。