git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Date handling.

From
Jan Harkes <jaharkes@cs.cmu.edu>
Date
Apr 25, 2005, 01:22 UTC
Message-ID
<20050425012216.GH29939@delft.aura.cs.cmu.edu>
In-Reply-To
<1114324729.3419.78.camel@localhost.localdomain>
On Sun, Apr 24, 2005 at 04:38:49PM +1000, David Woodhouse wrote:
Show 17 quoted lines
> On Sat, 2005-04-23 at 23:04 -0400, Jan Harkes wrote:
> > I noticed that some commit timestamps seemed to be off, looking into it
> > a bit more it seems like mktime is influenced by the setting of the
> > local TZ environment.
> 
> Ewww. I missed that in the documentation. I suppose I should have worked
> it out having empirically determined that it ignores the tm_gmtoff
> field.
> 
> > The question is, do we want to just calculate the time_t offset
> > ourselves without using mktime, or force the TZ environment to UTC.
> 
> I don't think we want to be in the business of counting leap seconds; we
> need to let the system do it. I don't much like setting TZ to UTC though
> -- how about we use your test case to find the offset and subtract that?
> 
> Does this work?

As Russ mentioned, that probably doesn't work with daylight savings time. However I did some testing and it looks like the following lines around mktime make it work as we would expect.

    tm.tm_isdst = -1;
    then = mktime(&tm);
    then += tm.tm_gmtoff;

Attached is the program I used to test it, it seems pretty much unfazed by changes to the TZ environment variable. Although I tested around a daylight savings time switch, I'm still not 100% sure if it doesn't mess up in some corner case.

Jan

#include <time.h> #include <stdlib.h> #include <stdio.h>

time_t mkutctime(struct tm *tm, int offset)
{
    time_t time;
    /* we don't know whether our timezone happens to be dst or not, let libc
     * figure that one out. */
    tm->tm_isdst = -1;
    /* interpret struct tm in the local timezone */
    time = mktime(tm);
    if (time == -1) return -1;
    /* libc lets us know how many seconds our local time differs from UTC
     * this is a non-standard BSD extension, which is probably not as
     * portable, but it seems to work. */
    time += tm->tm_gmtoff;
    /* However as the passed in struct tm was not UTC but in some other
     * timezone, we still have subtract the offset that came with the
     * RFC2822 date */
    time -= offset;
    return time;
}
int main(int argc, char **argv)
{
    struct tm tm = { 0, };
    time_t time;
    tm.tm_year = 70;
    tm.tm_mday = 1;
    time = mkutctime(&tm, 0);
    printf("1970-01-01 00:00:00 UTC = 0 (%d)\n", time);
    tm.tm_year = 105;
    tm.tm_mon = 2;
    tm.tm_mday = 17;
    tm.tm_hour = 20;
    tm.tm_min = 58;
    tm.tm_sec = 31;
    time = mkutctime(&tm, -5 * 3600);
    printf("2005-03-17 20:58:31 EST = 1111111111 (%d)\n", time);
    tm.tm_mon = 3;
    tm.tm_mday = 3;
    tm.tm_hour = 1;
    tm.tm_min = 59;
    tm.tm_sec = 59;
    time = mkutctime(&tm, -5 * 3600);
    printf("2005-04-03 01:59:59 EST = 1112511599 (%d)\n", time);
    tm.tm_hour = 3;
    tm.tm_min = 0;
    tm.tm_sec = 0;
    time = mkutctime(&tm, -4 * 3600);
    printf("2005-04-03 03:00:00 EDT = 1112511600 (%d)\n", time);
}
Previous: Russ AllberyNext: Russ Allbery
Message 11 of 13 in “Date handling.”
  1. David WoodhouseApr 14, 2005
  2. Linus TorvaldsApr 14, 2005
  3. Linus TorvaldsApr 14, 2005
  4. David WoodhouseApr 14, 2005
  5. tony.luck@intel.comApr 14, 2005
  6. David WoodhouseApr 14, 2005
  7. Jan HarkesApr 24, 2005
  8. James PurserApr 24, 2005
  9. David WoodhouseApr 24, 2005
  10. Russ AllberyApr 24, 2005
  11. Jan HarkesApr 25, 2005
  12. Russ AllberyApr 25, 2005
  13. David WoodhouseApr 14, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.