距离UTC - Linux上的LocalTime

时间:2010-11-12 16:20:28

标签: c++ c linux utc dst

我正在用C ++编写Linux(Ubuntu和Debian Lenny)应用程序。

现在我需要知道UTC与过去某一天当前设置的系统时间之间的距离/偏移。由于我需要转换记录的数据,因此需要根据过去的日期计算距离(可能具有与当天不同的DST设置)。

任何人都知道怎么做?

编辑:阅读第一个答案我认为我被误解了:我不想比较日期/时间。我有日期/时间值,我想从UTC转换为当地时间。

3 个答案:

答案 0 :(得分:3)

使用日期准备tm结构:

struct tm date;
memset(&date,0,sizeof(date));
date.tm_year = year - 1900;
date.tm_mon = month - 1;
date.tm_mday = day;
date.tm_hour = hour;
date.tm_min = minute;
date.tm_sec = second;
date.tm_isdst = -1; // VERY IMPORTANT

mktime(&date); /// fill rest of fields

然后查看tm_gmtoff

printf("%d\n",date.tm_gmtoff);

这是与UTC的距离。

现在这是Linux和BSD特有的,它不适用于其他系统,这是有效的 关于夏令时。

阅读man mktime以获取更多信息。并使用正确的值填充struct tm

P.S。:从UTC转换为本地和返回?

time_t posix_time = timegm(&UTC_Filled_struct_tm); // Linux specific line
localtime_r(&posix_time,&local_Filled_struct_tm);

本地到UTC

time_t posix_time = mktime(&local_Filled_struct_tm);
gmtime_r(&posix_time,&UTC_Filled_struct_tm);

答案 1 :(得分:2)

我认为您可以从使用Boost.DateTime或ICU中受益。

至于Boost.DateTime tt可能是这样的:

1)您准备一个包含时区信息Boost.Datetime的数据库并创建一个时区。时区非常重要,因为它们包含有关DST的信息

tz_database tz_db;
tz_db.load_from_file("./date_time_zonespec.csv");
time_zone_ptr nyc = tz_db.time_zone_from_region("America/New_York"); // or other timezone


或者只是创建一个这样的时区。

std::string kaliningrad_string = "EET+02:00:00EEST+01:00:00,M3.5.0/02:00:00,M10.5.0/03:00:00";
boost::local_time::time_zone_ptr kaliningrad_tzone_posix(new boost::local_time::posix_time_zone(kaliningrad_string));
std::string vladivostok_string = "VLAT+10:00:00VLAST+01:00:00,M3.5.0/02:00:00,M10.5.0/03:00:00";
boost::local_time::time_zone_ptr vladivostok_tzone_posix(new boost::local_time::posix_time_zone(vladivostok_string));

使用时区的字符串规范创建时区看起来更加困难,但如果在date_time_zonespec.csv中找不到特定的时区,则可以使用它。 例如,萨马拉曾经在2010年3月之前使用UTC + 4,现在是UTC + 3。 date_time_zonespec.csv没有更改历史记录,因此在这种情况下,必须从字符串规范中创建时区。但是我记得ICU似乎有这种历史的时区ICU TimeZone Classes

  

时区数据经常变化   回应周围的政府   世界改变他们的地方规则和   它们适用的领域。 ICU   为每个更新时区数据   释放,以及最简单的留下来   最新的可能是升级到   最新的ICU发布,也   提供错误修复,代码改进   和其他功能。


3)建立您需要的本地时间,例如

local_date_time tmp(boost::gregorian::date(2010, 3, 28), boost::posix_time::time_duration(1,59,0),nyc, boost::local_time::local_date_time::EXCEPTION_ON_ERROR);

4)然后使用函数utc_timelocal_time来计算差异 该页面上有一个示例:

ptime pt(date(2004,Nov,5), 
         hours(10));
time_zone_ptr zone(new posix_time_zone("MST-07"));
local_date_time az(pt, zone);
az.utc_time(); // 10am 2004-Nov-5
az.local_time(); // 3am 2004-Nov-5


5)另一个例子。本地时间相同但UTC不同

local_date_time tmp(boost::gregorian::date(2010, 3, 28), boost::posix_time::time_duration(1,59,0),kaliningrad_tzone_posix, boost::local_time::local_date_time::EXCEPTION_ON_ERROR);
std::cout << "As is: " << tmp << ", UTC: "  << tmp.utc_time() << std::endl;

local_date_time tmp(boost::gregorian::date(2010, 3, 28), boost::posix_time::time_duration(1,59,0),vladivostok_tzone_posix, boost::local_time::local_date_time::EXCEPTION_ON_ERROR);
std::cout << "As is: " << tmp << ", UTC: "  << tmp.utc_time() << std::endl;

答案 2 :(得分:0)

确保所有时间都转换为UTC(例如,请参阅mktime())。然后,您可以使用同一链接中的difftime()或timeval_subtract示例函数,具体取决于存储时间的结构。