5

我在 UTC 中存储消息。因此,如果有人回顾之前的消息,我需要能够将时间戳转换为相对于当时时区的时间。我如何获得当时的时区?

例如,2012 年 9 月 3 日的时区是 PDT。当前时间偏移量为 -0700。我在 9:06 发送了一条消息。UTC 时间是 16:06。

我在 2012 年 12 月 1 日返回此消息。当前时区是 PST。当前时间偏移量为 -0800。我查看了我在 2012 年 9 月 3 日发送的消息。如果我要使用当前时间偏移从 UTC 转换回来,我会得到 8:06,这不是发送消息的时间。它是在 9:06 发送的。

因此,我需要一种方法来找出 2012 年 9 月 3 日的时区是 PDT,而不是 PST。

没有库的 PS 将是最好的,谢谢。

4

3 回答 3

3

Boost Date_time 就是这样做的,这是我一直闲逛的简单示例(下面的代码):

edd@max:~/src/progs/C++$ g++ -o boost_posix_time_dst boost_posix_time_dst.cpp
edd@max:~/src/progs/C++$ ./boost_posix_time_dst 
DST ran from 2012-Mar-11 02:00:00 to 2012-Nov-04 02:00:00
DST shortcut PDT
DST name     Pacific Daylight Time
edd@max:~/src/progs/C++$ 

还有形成日期的功能(您的 2012 年 12 月 1 日)并查看它是否在给定间隔内(如此处由 DST 开始和结束形成的那样)。

我认为您也可以通过形成日期并检查 isDST() 布尔值来获得它。

我的短节目如下。您需要 csv 文件的本地副本,它是 a) 在 Boost 源中和 b) 在许多处理时区的网站上(例如 Google 的第一次或第二次点击在 CERN 找到它):

#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>  
#include <boost/date_time/local_time/local_time.hpp>     

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

int main(int argc, char **argv) {

  boost::local_time::tz_database tz;
  tz.load_from_file("/tmp/date_time_zonespec.csv");

  boost::local_time::time_zone_ptr tzp =
            tz.time_zone_from_region("America/Los_Angeles");    

  int year = 2012;
  boost::posix_time::ptime t1 = tzp->dst_local_start_time(year);
  boost::posix_time::ptime t2 = tzp->dst_local_end_time(year);
  std::cout << "DST ran from " << t1 << " to " << t2 << std::endl;
  std::cout << "DST shortcut " << tzp->dst_zone_abbrev() << std::endl;
  std::cout << "DST name     " << tzp->dst_zone_name() << std::endl;

}
于 2012-09-03T16:27:19.010 回答
3

如果它是一个简单的C++应用程序,在执行期间不需要使用单独的时区,那么您可以简单地使用localtime来获取一个共享引用,其中包含调用它struct tm *的特定时区信息。time_t如果您的系统配置了 PST 时区,那么当您调用 时localtime,它将使用太平洋时区信息进行显示 - 使用 2012 年 1 月 1 日(格林威治标准时间)和 2012 年 6 月 1 日的示例:

time_t def_time = 1325376000;
struct tm *a_tim = localtime(&def_time);
printf("%s %ld %d\n", a_tim->tm_zone, a_tim->tm_gmtoff, a_tim->tm_isdst);
def_time = 1338505200;
a_tim = localtime(&def_time);
printf("%s %ld %d\n", a_tim->tm_zone, a_tim->tm_gmtoff, a_tim->tm_isdst);

在我的系统(TZ=Europe/Dublin)上显示:

GMT 0 0
IST 3600 1

通过用 America/Los_Angeles 覆盖 TZ 环境变量,我得到:

PST -28800 0
PDT -25200 1

即系统能够很好地确定时区名称、与 GMT 的偏移量以及夏令时是否从 UTC 时间戳开始生效。

编辑:尝试使用 posix 提供的时区例程同时在 C/C++ 程序中使用多个时区是可怕的,如果您处于这种情况,我绝对建议您使用 boost,因为它是一个快速的解决方案。

于 2012-09-03T17:04:40.873 回答
0

仅知道当前偏移量并不足以告诉您一年中另一个时间同一位置的偏移量;有很多地点在一年中的部分时间共享一个时区(例如中欧和阿尔及利亚,或美国东部和哥伦比亚)。

最简单的解决方法是将时区与消息一起存储。

于 2012-09-03T16:25:16.610 回答