Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unix.mktime fails or is incorrect on Windows #6215

Closed
vicuna opened this issue Oct 29, 2013 · 7 comments
Closed

Unix.mktime fails or is incorrect on Windows #6215

vicuna opened this issue Oct 29, 2013 · 7 comments

Comments

@vicuna
Copy link

vicuna commented Oct 29, 2013

Original bug ID: 6215
Reporter: daweil
Assigned to: @protz
Status: closed (set by @xavierleroy on 2015-12-11T18:24:18Z)
Resolution: not a bug
Priority: normal
Severity: major
Platform: mingw
OS: Windows
Version: 4.01.0
Category: otherlibs

Bug description

Function Unix.mktime fails in windows for time <= 3599 seconds
and is incorrect for time > 3600. seconds.

note that it works fine in a cygwin shell, but fails outside (in a DOS shell)

Steps to reproduce

compile the attached ml file :
ocamlbuild bugMkTime.native -tag use_unix -no-links
then
_build/bugMkTime.native

In a "Dos" or "MsysGit" shell, the output is
more than one hour is 1.000000 second
one hour is 0.000000 second
Fatal error: exception Unix.Unix_error(32, "mktime", "")

while in a cygwin shell (with the same executable file), the output is correct :
more than one hour is 3601.000000 second
one hour is 3600.000000 second
less than one hour is 3599.000000 second

File attachments

@vicuna
Copy link
Author

vicuna commented Oct 29, 2013

Comment author: @protz

Are you positive that you're running the exact same executable?

@vicuna
Copy link
Author

vicuna commented Nov 3, 2013

Comment author: daweil

Yes.
The executable is build once with ocamlbuild in cygwin.
And executed first in cygwin and then outside in a Dos shell.

Can you reproduce the issue on one of your machine ?

@vicuna
Copy link
Author

vicuna commented Nov 4, 2013

Comment author: @protz

Yes, I can confirm. This is strange indeed.

@vicuna
Copy link
Author

vicuna commented Nov 4, 2013

Comment author: @protz

The Cygwin shell defines the TZ environment variable while the Windows shell does not. This is what's causing the difference in behavior. To reproduce the error in a Cygwin shell, just run

unset TZ

then launch your test program.

@vicuna
Copy link
Author

vicuna commented Nov 4, 2013

Comment author: @protz

The underlying problem has something to do with DST (Dayling Saving Time). I strongly suspect this is not a bug, in the sense that:

  1. the same problem happens on Linux
protzenk@sauternes:/tmp $ TZ=Europe/Paris ./a.out 
more than one hour is 1.000000 second
one hour is 0.000000 second
Fatal error: exception Unix.Unix_error(32, "mktime", "")
protzenk@sauternes:/tmp $ TZ=USA/New_York ./a.out 
more than one hour is 3601.000000 second
one hour is 3600.000000 second
less than one hour is 3599.000000 second

and 2)
i) the documentation says in a fairly explicit manner that gmtime returns a tm struct whose tm_isdst field is always 0 (see http://msdn.microsoft.com/en-us/library/0z9czt0w.aspx)
ii) both the windows and the unix implementation of OCaml's mktime set tm_isdst to -1, thus leaving it up to the environment to determine whether DST is active in the system's TZ or not (http://msdn.microsoft.com/en-us/library/d1y53h2a.aspx).

The conclusion is, the date returned by gmtime(3599.), when interpreted with DST on or off, I have no idea which, represents one second before the epoch, thus a date that's not representable, hence the ERANGE message.

The documentation explicitly says that the tm argument of mktime is interpreted in the local time zone http://caml.inria.fr/pub/docs/manual-ocaml/libref/Unix.html

@vicuna
Copy link
Author

vicuna commented Nov 4, 2013

Comment author: @protz

I'm marking this as no change required, since I strongly suspect nothing's wrong with OCaml.

@vicuna
Copy link
Author

vicuna commented Nov 4, 2013

Comment author: daweil

OK. As the behavior is surprising, could you just add something in the documentation of the gmtime function ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant