bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: what shall we do with the drunken time_t ?


From: Bruno Haible
Subject: Re: what shall we do with the drunken time_t ?
Date: Tue, 25 Apr 2017 21:09:18 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-72-generic; KDE/5.18.0; x86_64; ; )

Hi Paul,

> Couldn't asctime be causing the problem, insted of stat, gmtime etc.?

No, the problem is really with stat(). In my test program I had decomposed
the time_t into days, hours, seconds myself:
        int day = tt / (24*3600);
        int hour = (tt / 3600) % 24;
        int seconds = tt % 3600;
        fprintf (stdout, "mtime = %d %d %d\n", day, hour, seconds);

And the time() function appears to follow the POSIX semantics. New test program:
====================================================================
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static void show_time (const char *label, time_t tt)
{
        int day = tt / (24*3600);
        int hour = (tt / 3600) % 24;
        int seconds = tt % 3600;
        fprintf (stdout, "%s = %d %d %d\n", label, day, hour, seconds);
        fprintf (stdout, "  as GMT: %s", asctime (gmtime (&tt)));
        fprintf (stdout, "  as localtime: %s", asctime (localtime (&tt)));
}

int main (int argc, char *argv[])
{
        int i;
        {
                show_time ("now", time(NULL));
        }
        for (i = 1; i < argc; i++) {
                const char *filename = argv[i];
                struct stat buf;
                if (stat (filename, &buf) < 0) { perror("stat"); exit(1); }
                fprintf (stdout, "File %s ", filename);
                show_time ("mtime", buf.st_mtime);
        }
}
====================================================================

Output without the asctime lines:


German timezone (= GMT + 1h + dst, DST currently enabled):

$ ./stat-file-cygwin.exe n.txt t.tar
now = 17281 16 1665
File n.txt mtime = 17261 1 2961
File t.tar mtime = 17132 18 1920

$ ./stat-file-msvc.exe n.txt t.tar
now = 17281 16 1700
File n.txt mtime = 17261 2 2961
File t.tar mtime = 17132 19 1920

$ ./stat-file-mingw.exe n.txt t.tar
now = 17281 16 1781
File n.txt mtime = 17261 2 2961
File t.tar mtime = 17132 20 1920

Israel timezone (= GMT + 2h + dst, DST currently enabled):

$ ./stat-file-cygwin.exe n.txt t.tar
now = 17281 16 2356
File n.txt mtime = 17261 1 2961
File t.tar mtime = 17132 18 1920

$ ./stat-file-msvc.exe n.txt t.tar
now = 17281 16 2358
File n.txt mtime = 17261 3 2961
File t.tar mtime = 17132 20 1920

$ ./stat-file-mingw.exe n.txt t.tar
now = 17281 16 2359
File n.txt mtime = 17261 3 2961
File t.tar mtime = 17132 21 1920

You can see that:
  * The time_t values from time(NULL) are not affected by the time zone.
  * The time_t values from stat() are affected by the time zone in MSVC and 
mingw.
    The offset is
      - for MSVC: timezone offset (1 h in German timezone, 2 h in Israel 
timezone)
      - for mingw: buggy (1 h or 2 h in German timezone, 2 h or 3 h in Israel
        timezone, depending on the file)

By the way, as soon as I change the timezone from German timezone to Israel
timezone, the Notepad++ editor tells me that all files have changed on disk and
asks whether I want to reload them (one by one!). This is really a symptom of
the stat() bug.

> Let's put it this way: Emacs ports to mingw and does not worry about gmtime 
> returning a value disagreeing with POSIX. And Emacs does not use asctime (it 
> uses strftime instead).

Emacs also appears to not use st_mtime of opened files (at least not by 
default).
But if it warned the user about files modified in the background (like Nodepad++
and KDE kate do), it would exhibit the same symptom.

Bruno




reply via email to

[Prev in Thread] Current Thread [Next in Thread]