Given a Date/Time as a string, what is the best way to know if it was DST at that time?

感情迁移 提交于 2019-12-11 04:59:32

问题


Let's say I'm given a string such as this: "2009-4-9", meaning April 9th, 2009. Assuming for starters, that I am only concerned with local time (I have concerns about other time zones as well, but I'll tackle the easy stuff first). What is the best way to know if Daylight Savings was in effect at that time?

You can assume that the system has the properly updated timezone files such as /etc/localtime and I am interested in portable solutions. Either c or c++ are acceptable as well.

You can also assume that I only care about past or present dates, never the future.

Currently I have a "hack" which looks like this (I know localtime_r is a library extension, but it's close enough to the same functionality that I can make it portable)

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);
}

While this works (and seems to be a pretty effective way), I feel like it's silly to be converting back and forth. Is there a better way?


回答1:


You do not need to call localtime_r() at all. mktime() normalises the struct tm that you pass it, including setting tm_isdst to a nonnegative value if it was passed in set to -1. So all you need is:

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);
}

This behaviour of mktime() is required by the C standard; for example, C99 says:

The mktime function converts the broken-down time, expressed as local time, in the structure pointed to by timeptr into a calendar time value with the same encoding as that of the values returned by the time function. The original values of the tm_wday and tm_yday components of the structure are ignored, and the original values of the other components are not restricted to the ranges indicated above.276 On successful completion, the values of the tm_wday and tm_yday components of the structure are set appropriately, and the other components are set to represent the specified calendar time, but with their values forced to the ranges indicated above; the final value of tm_mday is not set until tm_mon and tm_year are determined.

with footnote 276 explicitly addressing the tm_isdst member:

276) Thus, a positive or zero value for tm_isdst causes the mktime function to presume initially that Daylight Saving Time, respectively, is or is not in effect for the specified time. A negative value causes it to attempt to determine whether Daylight Saving Time is in effect for the specified time.




回答2:


The conversion from UTC to local time is not a reversible function. For example, in the autumn when the clocks jump back an hour, the local times between 02:00 and 03:00 occur twice. Given a time in this interval, it's not possible to determine whether the local time happened at a specific UTC time in local daylight time, or one hour later in local standard time.




回答3:


I have done many time conversions before in C and I think you pretty much have it the way I would have done it too. As far as I know, localtime_r and its relatives may be your only option (unless there is some third party date library.) Of course, Greg Hewgill is correct for the "gray hour" between time switches.



来源:https://stackoverflow.com/questions/9403015/given-a-date-time-as-a-string-what-is-the-best-way-to-know-if-it-was-dst-at-tha

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!