B19: wrong reading of date formats

Richard M. Heiberger rmh@fisher.stat.temple.edu
Wed Mar 3 11:37:00 GMT 1999

The screen saver distributed with the IBM Thinkpad has a date stamp
  Jan 1, 2105
bash and almost all other programs get it wrong.

I sent the file to Andrew Innes at Ntemacs <andrewi@harlequin.co.uk>.
His analysis responding to my query is attached.  A copy of the file
in zipped format to retain the date stamp is at

From: Andrew Innes <andrewi@harlequin.co.uk>
To: rmh
Subject: Re: file with weird date

On Sun, 28 Feb 1999 01:58:48 -0500, rmh@fisher.stat.temple.edu (Richard M. Heiberger) said:
>  (downloaded binary)
>Thinkpad 600 running Windows98 
>There are two issues as it turns out.
>First, dired can't handle WIN386.SWP at 167772160.0
>This might be the issue addressed in the ntemacs-users last week,
>although I thought that was a problem and fixed for 20.3.6

Yes, it was introduced by a change in 20.3.6 and is being fixed.

>Second, c:/windows/system/THINK1.SCR has an illegal date,
>hence dired can't read the entire directory c:/windows/system/
>Both Screen Savers THINK[12].SCR work.

Right - Emacs knows that the timestamps on these files are out of range,
and therefore throws an error.  (More precisely, Emacs is calling
localtime() to decode the timestamp returned by file-attributes aka stat
so it can print it.  It is localtime that is barfing on the timestamp.)

>1.  c:/
>Windows Explorer does not show a date for c:/
>(or anything else on "My Computer")

The root directory on any drive doesn't appear in any directory (even
itself - there is no "." entry), so there simply isn't any available
date or permission information.

Emacs uses default values for root directories.

>2. c:/windows
>a. emacs
>C-x  c:/windows
>Arithmetic range error: "truncate", 167772160.0

This is the ls-lisp bug introduced in 20.3.6.

>3. c:/windows/system
>a. emacs
>Specified time is not representable

This is the expected behaviour when ls-lisp tries to convert a time that
is out of range.  (Of course, it would be better for ls-lisp to catch the
error, do something useful for that file, and continue.  I'll look into
making that change.)

A valid question arises as to how file-attributes can return a time that
is out of range - it turns out that our version of stat() is treating
time_t as an unsigned int, while localtime() from MSVC's CRT treats it
as signed, and negative values are apparently invalid.  So it seems that
the timestamp on these screen savers must be far into the future (beyond
2038), because our implementation of stat() always returns 0 for
timestamps that are earlier than 1970.

[Confirmed - the timestamp is Jan 1, 2105.]

>b. bash (B19)
>//d/rmh$ ls -alF c:/windows/system/THINK*
>-rw-r--r--  1 500    everyone   169984 Nov 25  1968 c:/windows/system/THINK1.SCR
>-rw-r--r--  1 500    everyone   172032 Nov 25  1968 c:/windows/system/THINK2.SCR

I guess the cygwin library, or ls, just lets the time_t value wrap
around, or perhaps treats it as unsigned.

[Jan 1, 2105 is roughly 13.x months from the end of the unsigned time_t
range, and Nov 25, 1968 is about the same distance from the beginning of
the time_t epoch, so it looks like Cygnus ls has ignored the high bit of
the timestamp.]

>c. DOS
>D:\emacs\ess\lisp>dir c:\windows\system\think*
> Volume in drive C has no label
> Volume Serial Number is 0E51-15DE
> Directory of C:\WINDOWS\SYSTEM
>THINK1   SCR       169,984  01-01-99 12:00a THINK1.SCR
>THINK2   SCR       172,032  01-01-99 12:00a THINK2.SCR
>         2 file(s)        342,016 bytes
>         0 dir(s)     570,032,128 bytes free

I have no idea what command.com is doing!  Clearly these timestamps are
meaningless, because nothing else would have a problem with them if they
were correct.

>d. Windows Explorer
>THINK1.SCR 166KB Screen Saver 1/2/05 12:00 AM
>THINK2.SCR 168KB Screen Saver 1/2/05 12:00 AM

This also doesn't seem right.  Emacs and Cygnus ls wouldn't have
problems if these timestamps were correct (assuming 05 means 2005).

[Okay, see below; the timestamp seems to be 2105, not 2005.  Looks like
Explorer (and pkunzip and Info unzip) has a y2100 problem!  Actually, if
you look at the Properties of the file in Explorer, you will see it
shows the timestamp correctly.]

>This is an interesting file.  tar wouldn't take it.
>/windows/system$ tar cf //d/rmh/ntemacs/think.tar THINK1.SCR 
>tar: THINK1.SCR: is unchanged; not dumped
>gzip/gunzip won't take it
>//d/tmp$ gzip THINK1.SCR
>gzip: THINK1.SCR.gz: Invalid argument
>//d/tmp$ gunzip -N  THINK1.SCR
>gunzip: THINK1.SCR: Invalid argument
>cp won't take it
>//d/rmh/ntemacs$ cp -p THINK1.SCR think1.scr.copy
>cp: think1.scr.copy: Invalid argument

The above seems to imply the cygwin time functions treat negative time_t
values as invalid, as do the MSVC time functions.

>Windows Explorer can copy it.

Explorer will be using the native OS CopyFile routine, which probably
doesn't even try to interpret the timestamp directly, but just copies it
bitwise.  Anyway, the timestamp is presumably valid for OS functions,
which is what Explorer will be using.

>pkzip seems to handle it.

Being a DOS program, timestamps are in an encoded format where all
possible values are meaningful.  It just seems to be Unix (and the Unix
emulation in cygwin and MSVC) that chose an encoding where some values
are considered invalid.

>Searching ZIP: THINK1.ZIP
> Length  Method   Size  Ratio   Date    Time    CRC-32  Attr  Name
> ------  ------   ----- -----   ----    ----   -------- ----  ----
> 169984  DeflatN  61477  64%  01-01-05  00:00  1783b82b --w-  THINK1.SCR
> ------          ------  ---                                  -------
> 169984           61477  64%                                        1

Year "05" 

>emacs C-x C-f in (Zip-Archive Narrow)
>M Filemode      Length  Date         Time      File
>- ----------  --------  -----------  --------  ----------
>  -rw-rw-rw-    169984   1-Jan-2105  00:00:00  think1.scr
>- ----------  --------  -----------  --------  ----------
>                169984                         1 file

Here Emacs actually gets it right!  (arc-mode is parsing the zip TOC
itself btw).

>pkunzip and unzip95 both restore the original date.

It looks like the zip format stores timestamps as unsigned ints, so the
maximum date is something like early-February 2106.


Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

More information about the Cygwin mailing list