Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

[closed] date_and_time incorrect in cygwin

martenjan
Beginner
2,045 Views

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.

[plain]
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
[/plain]

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:
[plain]
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.
[/plain]

The following is the source of my program:
[fortran]
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
[/fortran]

0 Kudos
9 Replies
mecej4
Honored Contributor III
2,045 Views

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.

0 Kudos
martenjan
Beginner
2,045 Views

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.

[plain]

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

[/plain]

Maybe you can spot the problem.

Thanks for the effort,

Marten Jan

0 Kudos
TimP
Honored Contributor III
2,045 Views

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.

0 Kudos
Steven_L_Intel1
Employee
2,045 Views

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.

0 Kudos
martenjan
Beginner
2,045 Views

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.

0 Kudos
fortrandave
New Contributor I
2,045 Views

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

0 Kudos
fortrandave
New Contributor I
2,045 Views

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

[fortran]
    success = SETENVQQ('TZ=""')
    call date_and_time(yymmdd, hhmmsshs, zone=z)
[/fortran]

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

Thanks,
Dave

0 Kudos
IanH
Honored Contributor III
2,045 Views

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.

0 Kudos
fortrandave
New Contributor I
2,045 Views

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:

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

Thanks,
Dave

0 Kudos
Reply