如果将日期/时间作为字符串,那么知道当时是否为DST的最佳方式是什么?

时间:2012-02-22 21:07:56

标签: c++ c date time dst

假设我给了一个字符串,如:"2009-4-9",意思是2009年4月9日。假设对于初学者,我只关心当地时间(我也关注其他时区,但我先解决这个简单的问题。了解夏令时是否在当时生效的最佳方式是什么?

您可以假设系统具有正确更新的时区文件,例如/etc/localtime,我对便携式解决方案感兴趣。 c或c ++也是可以接受的。

你也可以假设我只关心过去或现在的日期,而不关心未来。

目前我有一个“黑客”看起来像这样(我知道localtime_r是一个库扩展,但它足够接近我可以使其移植的相同功能)

struct tm tm;
// convert the time string to a broken down structure in localtime
if(strptime("2009-4-9", "%Y-%m-%d", &tm)) {
    // convert the broken down structure into seconds since epoch
    const time_t t = mktime(&tm);

    // convert it back to a broken down structure, this seems pointless at first...
    // but libc will fill out fields such as tm_isdst
    localtime_r(&t, &tm);

    printf("DST : %d\n", tm.tm_isdst);
}

虽然这有效(并且似乎是一种非常有效的方式),但我觉得来回转换是愚蠢的。还有更好的方法吗?

3 个答案:

答案 0 :(得分:4)

您根本不需要致电localtime_r()mktime()会将您传递的struct tm标准化,包括将tm_isdst设置为非负值,如果它已设置为-1。所以你需要的只是:

struct tm tm = { 0 };
// convert the time string to a broken down structure in localtime
if(strptime("2009-4-9", "%Y-%m-%d", &tm)) {
    tm.tm_isdst = -1;
    // normalise the broken down structure - this calculates tm_isdst
    mktime(&tm);

    printf("DST : %d\n", tm.tm_isdst);
}

C标准要求mktime()的这种行为;例如,C99说:

  

mktime函数转换故障时间,表示为   当地时间,timeptr指向日历的结构   时间值与返回值的编码相同   time函数。 tm_wday和。{的原始值   结构的tm_yday个组件将被忽略,而原始组件则被忽略   其他组件的值不限于范围   如上所述。 276 成功完成后,其值为   设置了结构的tm_wdaytm_yday组件   适当地,并且其他组件被设置为代表   指定的日历时间,但其值被强制为范围   如上所述;直到tm_mday的最终值才设置   tm_montm_year已确定。

脚注276明确指出tm_isdst成员:

  

276)因此,tm_isdst的正值或零值会导致mktime   函数最初分别假设夏令时,   在指定时间内有效或无效。负值会导致   它试图确定夏令时是否有效   在指定的时间。

答案 1 :(得分:2)

从UTC到本地时间的转换不是可逆功能。例如,在秋天,当时钟跳回一小时,02:00和03:00之间的当地时间出现两次。如果在此时间间隔内有一段时间, 可能无法确定本地时间是在本地日光时间内的特定UTC时间发生的,还是在本地中一​​小时后发生的标准时间。

答案 2 :(得分:1)

我之前在C中做了很多次转换,我觉得你也很喜欢我的做法。据我所知,localtime_r及其亲属可能是你唯一的选择(除非有一些第三方日期库。)当然,Greg Hewgill对于时间切换之间的“灰色小时”是正确的。