Problems with time (now) Linux and Windows

Started by ale870, August 06, 2009, 08:32:05 AM

Previous topic - Next topic

ale870

Hello,



I just discovered a problematic behaviour in newLisp.



I installled newLisp on a Linux and on a Windows computer.



If I use the function (now) on Linux it supply the correct offset values:


> (now)
(2009 8 6 15 32 0 826945 218 5 -120 0)


Instead on Windows I receive a strange result:


> (now)
(2009 8 6 15 26 39 844033 218 5 2089937716 3473408)


Please note that Windows and Linux time works well (show the correct date/time).



Where is the problem in Windows environment?



Thank you!
--

Lutz

#1
Unfortunately this has been broken for a long time on Win32 or working unreliable (at least since v9.3). Not sure when this will be fixed.

ale870

#2
But the is related to Windows API or to newLisp implementation?
--

Lutz

#3
I just made it work. It will be in the next development version. It will be as described in the manual.

ale870

#4
:-) You are my hero Lutz (I'm joking!)



This fix is very important even for FOOP-Time.lsp module created by Cormullion, since that module does NOT work on Windows for this problem.



Thank you again!
--

cormullion

#5
Thanks Alessandro - I didn't realise that (now) didn't work. timeutilies depends on (now) working...

Lutz

#6
It's the last two fields: "minutes west of GMT" and "daylight savings time", which didn't work on many OSs. On Mac OS X at least the minutes-west field was working correctly.



In version 10.1.3, to be released this weekend, both fields are working on: Mac OS X, Win32, SunOS and Ubuntu LINUX.



On FreeBSD and OpenBSD, at least on the machines, I have access to, 0 is returned for both fields, which may be caused by a missing time-zone configuration on this machines (e.g. FreeBSD on nfshost and OpenBSD on m64 (Ted Walther?!)



Machines need to be supplied with a time-zone database containing data for different geographical areas in the world. If this is missing, 0 is returned on both fields.

TedWalther

#7
Quote from: "Lutz"It's the last two fields: "minutes west of GMT" and "daylight savings time", which didn't work on many OSs. On Mac OS X at least the minutes-west field was working correctly.



In version 10.1.3, to be released this weekend, both fields are working on: Mac OS X, Win32, SunOS and Ubuntu LINUX.



On FreeBSD and OpenBSD, at least on the machines, I have access to, 0 is returned for both fields, which may be caused by a missing time-zone configuration on this machines (e.g. FreeBSD on nfshost and OpenBSD on m64 (Ted Walther?!)



Machines need to be supplied with a time-zone database containing data for different geographical areas in the world. If this is missing, 0 is returned on both fields.


I checked, timezone is properly configured (look at /etc/localtime, it is a link to a file in /usr/share/zoneinfo, which is a precompiled timezone file)  Lots of info in the "zic" manpage, which stands for zone-info-compiler.



From the manpage of gettimeofday():


Quote
int gettimeofday(struct timeval *tv, struct timezone *tz);



       The  use  of the timezone structure is obsolete; the tz argument should normally be specified as NULL.  The tz_dsttime field has never been used under Linux; it has not been and will not be sup‐

       ported by libc or glibc.  Each and every occurrence of this field in the kernel source (other than the declaration) is a bug.  Thus, the following is purely of historic interest.


May I recommend removing the last two fields from being returned by (now)?
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

cormullion

#8
Quote from: "TedWalther"May I recommend removing the last two fields from being returned by (now)?


Or rather, by documenting their problems? Otherwise code would break with 'list out of bounds'.

Lutz

#9
The only place where I have used 'struct timezone' was for the _BSD flavor and after checking this documentation for time.h:



http://fxr.watson.org/">http://fxr.watson.org/



For Mac OS X, UBUNTU Linux and SunOS I am using the GNU 'C' predefined variables 'int timezone' and 'int daylight'. But they don't work on FreeBSD  and OpenBSD. For Mac OSX 'struct timezone' works too, but I wen with 'int timezone' and 'int daylight', as hey are more common.



We have it working now on Mac OS X, UBUNTU Linux, SunOS and Win32, so I will not drop it just because it doesn't work FreeBSD/OpenBSD ;-).







Ps: also found tm_gmtoff, and ltm->tm_isdst in 'struct tm' on BSDs, but they don't work either.



There must be a way to do this correctly on the BSD's, can somebody help? Specially FreeBSD is important as it is used so frequently at ISPs.

TedWalther

#10
Lutz, are you calling tzset to populate the extern char *tzname[2]; variable?
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

TedWalther

#11
I just checked; the gmtime() and localtime() calls on OpenBSD 4.4 do return the correct data.



The tm_isdst field is an integer that indexes the tzname external variable, which contains the name of the timezone.  Here is the output of a test program I wrote:



tzname[0]: PST
tzname[1]: PDT
tm.tm_sec: 15
tm.tm_min: 29
tm.tm_hour: 16
tm.tm_mday: 8
tm.tm_mon: 7
tm.tm_year: 109
tm.tm_wday: 6
tm.tm_yday: 219
tm.tm_isdst: 1
tm.tm_gmtoff: -25200
tm.tm_zone: PDT


With the gmtime() function I would expect isdst and gmtoff to always be 0.  For localtime, you must run tzset() first.
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

TedWalther

#12
Here  is the source of the test program, perhaps you will find it useful to run it on the other platforms as well, perhaps the Mac OSX and SunOS platforms.



#include <sys>
#include <time>
#include <stdio>

extern char *tzname[2];

int
main(int argc, char** argv) {
        time_t t;
        struct tm *st;

        tzset(); // this populates tzname
        t = time(NULL);
        st = localtime(&t);
        printf("tzname[0]: %sn", tzname[0]);
        printf("tzname[1]: %sn", tzname[1]);
        printf("tm.tm_sec: %dn", st->tm_sec);
        printf("tm.tm_min: %dn", st->tm_min);
        printf("tm.tm_hour: %dn", st->tm_hour);
        printf("tm.tm_mday: %dn", st->tm_mday);
        printf("tm.tm_mon: %dn", st->tm_mon);
        printf("tm.tm_year: %dn", st->tm_year);
        printf("tm.tm_wday: %dn", st->tm_wday);
        printf("tm.tm_yday: %dn", st->tm_yday);
        printf("tm.tm_isdst: %dn", st->tm_isdst);
        printf("tm.tm_gmtoff: %dn", st->tm_gmtoff);
        printf("tm.tm_zone: %sn", st->tm_zone);
}
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

TedWalther

#13
Interesting, according to the GNU website, it is better to rely on the BSD method than on the extern timezone variable:



http://www.gnu.org/s/libc/manual/html_node/Time-Zone-Functions.html#Time-Zone-Functions">http://www.gnu.org/s/libc/manual/html_n ... -Functions">http://www.gnu.org/s/libc/manual/html_node/Time-Zone-Functions.html#Time-Zone-Functions


Quote
In GNU programs it is better to use tm_gmtoff, since it contains the correct offset even when it is not the latest one.


I just tested the BSD method on Ubuntu, and it does indeed work.  The essential 3 lines would be:



tzset();
t=time(NULL);
st=localtime(&t);


Except for Win32, I believe this should work on all Unixes from the past 10 years.  And maybe even on Win32!



Ted
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

TedWalther

#14
the problem is somehow in how stuffIntegerList() is being called.  Or maybe stuffIntegerList.  Because the call to localtime() is returning the correct info.  I verified this, after putting a call to tzset() in the main() function of newlisp.  Then I put in some printf debugging, verified that the correct values are coming out of localtime().  Once they are put into stuffIntegerList, what comes out the other end of the newLISP prompt is 0 and 0.



Is it a problem that tm_gmtoff is negative, and not positive?  the (UINT) cast looks possibly suspicious to me, although it didn't prevent printf() from accurately reporting the negative value when using the %d specifier.



Ted
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.