我正在用C ++编写Linux(Ubuntu和Debian Lenny)应用程序。
现在我需要知道UTC与过去某一天当前设置的系统时间之间的距离/偏移。由于我需要转换记录的数据,因此需要根据过去的日期计算距离(可能具有与当天不同的DST设置)。
任何人都知道怎么做?
编辑:阅读第一个答案我认为我被误解了:我不想比较日期/时间。我有日期/时间值,我想从UTC转换为当地时间。
答案 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_time
和local_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示例函数,具体取决于存储时间的结构。