[closed] date_and_time incorrect in cygwin

[closed] date_and_time incorrect in cygwin

I wrote a FORTRAN program using the date_and_time function. The source follows below. The date_and_time function returns the wrong time in the cygwin environment: I am not in UTC, so czone should be +0100. However, in the windows cmd environment, the results are correct. The question is now: Why does the date_and_time function not work properly in the cygwin environment, when compiled with the ifort compiler, whereas date() and time() do? Do I miss setting some environment variables? Should I use some compiler options? I have posted this question also in the Cygwin mailing list, but so far, I still have no clue about what may be wrong.

In the following output, the lines "ctime:..." to "milliseconds..." are based on time_and_date. The line 15:54:49 is the correct time obtained by the time function, and the line 23-JAN-13 is the correct date obtained by the date function.

ctime: 20130123 
cdate: 145449.947 
czone: -0000 
@ 2013-01-23 14:54:49.947 
  year                 2013 
  month                   1 
  day                    23 
  diff wrt UTC            0  minutes 
  hours                  14 
  minutes                54 
  seconds                49 
  milliseconds          947 
  15:54:49 
  23-JAN-13 
 

I have done some experiments to narrow down the problem:
* compiling with gfortran: time_gfortran.exe gives correct result in Cygwin
* compiling with g95: time_g95.exe gives the correct result in Cygwin
* compiling with ifort: time_ifort.exe gives the wrong time in Cygwin

After copying cygwin1.dll, cyggfortran-3.dll and cyggcc_s-1.dll to the working directory, I get correct results
using the three executables in c:\windows\system32\cmd.exe.

I suspect that the intel compiler does a different system call for time_and_date than for date and time. I am still baffled why the same source runs fine for gfortran and g95. Notice however that for these compilers, the _date_ and _time_ functions are not defined. Hence the preprocessor exclusion in the source.

Regards,

Marten Jan

The following example comes from the documentation:

Consider the following 
example executed on 2000 March 28 at 11:04:14.5:
INTEGER DATE_TIME (8)
CHARACTER (LEN = 12)
REAL_CLOCK (3)
CALL DATE_AND_TIME (REAL_CLOCK (1), REAL_CLOCK (2), &
                      REAL_CLOCK (3), DATE_TIME)

This assigns the value  "20000328" to REAL_CLOCK (1), the value "110414.500" to REAL_CLOCK (2), and the value "-0500" to REAL_CLOCK (3). The following values are assigned to DATE_TIME: 
2000, 3, 28, -300, 11, 4, 14, and 500. 
 

The following is the source of my program:

program time_and_date 
implicit none 
character (len=8)  cdate 
character (len=10) ctime 
character (len=5) czone 
integer(4) ival(8) 
integer(4) yr,mon,day,hr,min,sec,ms 
call date_and_time(cdate,ctime,czone,ival) 
read (cdate(1:4),*) yr 
read (cdate(5:6),*) mon 
read (cdate(7:8),*) day 
read (ctime(1:2),*) hr 
read (ctime(3:4),*) min 
read (ctime(5:6),*) sec 
read (ctime(8:10),*) ms 
print *,'cdate        ',cdate 
print *,'ctime        ',ctime 
print *,'czone        ',czone 
print "('@ ',i4,'-',i2.2,'-',i2.2,' ',i2.2,':',i2.2,':',i2.2,'.',i3.3)", yr,mon,day,hr,min,sec,ms 
print *,'year         ',ival(1) 
print *,'month        ',ival(2) 
print *,'day          ',ival(3) 
print *,'diff wrt UTC ',ival(4),' minutes' 
print *,'hours        ',ival(5) 
print *,'minutes      ',ival(6) 
print *,'seconds      ',ival(7) 
print *,'milliseconds ',ival(8) 
print * 
#ifdef IFORT 
   call time(ctime) 
   print *,ctime 
   call date(ctime) 
   print *,ctime 
#endif 
print *,'done' 
end program 
 

10 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.
Bild des Benutzers mecej4

As far as I know, IFort on Windows is completely Cygwin-agnostic, whereas Gfortran and G95 are quite Cygwin-dependent. The latter two compilers use the GNU C-library, which may return different values on the basis of Cygwin environmental variables such as LANG,  etc.

Unless you explicitly linked an IFort-compiled object with Cygwin libraries (which appears very unlikely), the results output by a program built with IFort will deliver the same output under CMD.exe or the Cygwin shell, in total disregard of any Cygwin variable settings.

Quote:

mecej4 wrote:

Unless you explicitly linked an IFort-compiled object with Cygwin libraries (which appears very unlikely), the results output by a program built with IFort will deliver the same output under CMD.exe or the Cygwin shell, in total disregard of any Cygwin variable settings.

That is what I would expect. Yet, the output is different, even when compiled using Visual Studio without any reference to cygwin. I used the following batch file to compile the source. Compiling using bash and compiling using c:\windows\system32\cmd.exe gives an executable with the same erroneous behavior under bash, but correct behavior under cmd.

set VS100COMNTOOLS=C:/Program Files/Microsoft Visual Studio 10.0/Common7/Tools/
set PATH=C:/Program Files/Intel/Composer XE 2011 SP1/bin/ia32/
set PATH=%PATH%;C:/Program Files/Intel/Composer XE 2011 SP1/redist/ia32/mkl/
set PATH=%PATH%;C:/Program Files/Common Files/Intel/Shared Libraries/redist/ia32/mpirt/
set PATH=%PATH%;C:/Program Files/Common Files/Intel/Shared Libraries/redist/ia32/compiler/
set PATH=%PATH%;C:/Program Files/Intel/MKL/10.0.1.015/ia32/bin/
set PATH=%PATH%;C:/Windows/
set PATH=%PATH%;C:/Windows/System32/
echo %PATH%
call "C:/Program Files/Intel/Composer XE 2011 SP1/bin/ifortvars.bat" IA32 VS2010
ifort.exe /fpp -DIFORT /stand:f90 /Qvc10 /Qlocation,link,"C:/Program Files/Microsoft Visual Studio 10.0/VC/bin" time_and_date.f90 /exe:time_ifort.exe

Maybe you can spot the problem.

Thanks for the effort,

Marten Jan

Compiling and running applications with ifort under a cygwin shell (typically bash, but you have several choices) is more analogous to using one of the mingw cross compilers, rather than the cygwin "native" gcc/gfortran which depend on cygwin .dll.

The mingw cross compilers support 64-bit mode (on Windows X64) which cygwin native compilers do not, but their complement of library function support is relatively limited.

I haven't explored the extent to which cygwin might permit you to set your system clock to UTC while giving applications a choice between UTC and local time.  Applications built for Windows native (mingw or Intel compilers) will see the system clock setting if you have set up such a mode, so they expect you to set system clock to local time.

Bild des Benutzers Steve Lionel (Intel)

I looked at the code that ifort uses for DATE_AND_TIME on Windows and it uses localtime to get the time and gmtime to compute the offset. That you get different results when you copy in a Cygwin DLL suggests to me that there is some older, buggy version of that DLL being found otherwise.

Since the program behaves correctly in a Windows shell and also when you copy in the Cygwin DLL, I would say this is a Cygwin issue.

Steve

I agree with the issue being a Cygwin one. Today, I noticed that the results are correct in my finite element program. The test program given in this thread also run correctly, I even did not recompile.

It is a bit unsatisfying that I still don't know the cause of the issue; I used the Cygwin Bash login terminal. I experimented on the other shells from Cygwin: the Cygwin Bash shell, the Cygwin Terminal and the Cygwin X-server, that starts an xterm. These shells have a more convenient cut ans paste behaviour. Nevertheless, I suspect that some configuration glitch has been corrected by using these shells, since also the Cygwin Bash login terminal.

I consider this issue closed.

Bild des Benutzers fortrandave

I've had this same issue with respect to Cygwin.  The following is what I find on my Win 7 system.

* If I open a cmd.exe window via the Windows start menu, the variable TZ is not set.
* If I open a Cygwin mintty window, the variable TZ is set to America/Chicago.
* If I run my application which uses date_and_time in Cygwin with TZ set, I get output with unexpected dates, e.g. log_common_20130314_150750.wri. (The format is log_common_YYYYMMDD_HHMMSS.wri.  It's around 9:07 am in St. Louis.  The 1507 would seem to mean that I'm getting UTC instead of local time, sort of.  Zone is returned as +1.  Subtracting an hour does get me to 1407 UTC.)
* If i first execute unset TZ, then execute my app in Cygwin, I get expected dates, e.g. log_common_20130314_090738.wri.  Zone is returned as -5.  Adding 5 also gets me to 1407 UTC.

So, there is an interaction between TZ and date_and_time.  Win 7 I believe still has the hardware clock set as local time instead of UTC -- unix-like systems use UTC.  This appears to mean that TZ set/not set and hardware clock is local/UTC are all factors affecting the output of date_and_time.  I believe my findings mean that TZ should be left unset under Windows but should be set on all unix-like platforms when the hardware clock is set to UTC.  Cygwin is a unix-like environment, so TZ has been set, but the hardware clock is set to localtime -- an unexpected configuration that gives unexpected results.  I don't know what Marten Jan's experience with other compilers means in relation to Intel.  Maybe Steve can comment on this?  At the least, i think this should help Marten and other Cygwin and Intel Fortran users understand what's going on.

Thanks,
Dave

Bild des Benutzers fortrandave

I'll add that unsetting TZ within the app has no effect on date_and_time output, e.g.

    success = SETENVQQ('TZ=""')
    call date_and_time(yymmdd, hhmmsshs, zone=z)

Am I doing something wrong, or is this expected behavior?

Thanks,
Dave

Some background that might be relevant - as Steve says, date_and_time calls the C library localtime.  The docs for the C library explain why TZ has an effect.  Simply changing the TZ environment variable may not be sufficient for the C library to recognise the change - see _tzset.

Bild des Benutzers fortrandave

Since my last comment, I've successfully unset TZ in my application.  Unsetting TZ has to be done in a program unit other than where date_and_time is called.  So, in my code, I unset TZ in one subroutine and call date_and_time after that in another subroutine.  Previously, I was calling setenvqq incorrectly -- the correction is shown below:

! Incorrect - the right hand side should not have "" - it should be blank.
    success = SETENVQQ('TZ=""')
! Correct
    success = SETENVQQ('TZ=')

Thanks,
Dave

Melden Sie sich an, um einen Kommentar zu hinterlassen.