64 bit dates

Started by TedWalther, October 17, 2010, 07:43:32 PM

Previous topic - Next topic

TedWalther

Most platforms have updated the Unix date functions to be 64 bit, so they can handle dates before 1970 and after 2032.  Can the newlisp implementation detect this on the fly and use it where possible?
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

#1
Also, does date-parse default to assuming the given date is in UTC timezone, or does it use local timezone?  I've tried altering the output with the %z and %Z specifiers, but not having much love.
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.

Lutz

#2
With your new configure-alt in the next version (thanks for the update), 64-bit date values will be possible in the future.



Except for 'date', which formats a date UTC value for the current timezone,  all other functions assume UTC as inputs and outputs:



'date-parse' assumes returns a UTC value for a UTC string

'date-value' assumes values given in UTC and outputs UTC

'date-list' takes UTC and gives a list of UTC (new since devopment 10.2.14)

'now' returns UTC values
; this way 'date-list' and 'date-parse' are complements:

(date-list (date-parse "2010.10.18 7:00" "%Y.%m.%d %H:%M"))
=> (2010 10 18 7 0 0 290 1)

; and 'date-value' and 'date-list' are complements:

(apply date-value (date-list 1287385200))
=> 1287385200

; 'now' is like 'date-list' but for now)

(apply date-value (now)) ; when executed at 2010.10.18 7:00 Eastern Time
=> 1287385200

(date-value) => 1287385200 ; when executed at 2010.10.18 7:00 Eastern Time

So basically all numbers are in UTC but formatting with 'date' is for the current timezone. 'date' and 'now' can take offset values in minutes.



ps: 'date-parse' same as 'parse-date', with the new 'date-list', we have now 3 date-xxx functions : 'date-list', 'date-parse', 'date-value'.



ps: Unfortunately the Daylight Savings Time (DST) value in 'now' is different on LINUX/UNIX and MS Windows, and not always present on some UNIXs.

cormullion

#3
For the confused or forgetful, like me, the date-list function isn't in the current version 10.2.8 but is in the current development version 10.2.16.



:)

TedWalther

#4
With date-parse, I tried setting the timezone, and putting %z or %Z in the format string.  It didn't seem to affect the result though.  Maybe the underlying strftime function is ignoring it?  This is on Ubuntu 64bit.
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.

Lutz

#5
The %Z and %z parameters work only for the format in 'date', but are ignored when parsing dates.
> (date (date-value) 0 "%Y-%m-%d %H:%M %Z")
"2010-10-18 20:00 EDT"
>

'date-parse' only pays attention to year, month, date, hour, minutes and seconds.

TedWalther

#6
I note that the offset in the date function is relative to local time, not UTC.  Is that a bug, or intentional?  If I'm working in UTC, then suddenly the date function works with local time, perhaps some extra utility functions are needed?  Should I make a table of all time-zones, so I can figure out the local timezone, then figure out the difference between it and my target timezone?



I have a bunch of times in UTC of astronomical events.



I want to display them in the "local time" of various points on earth where they may be viewed, so people can find out what is their local time to view the said event.



For instance, (date 'lunar-conjunction -420) didn't give the results I expected.  And finding the date one timezone over didn't work either; (date 'lunar-conjunction -360)



Would a string format of some sort help?



I tried using (env "TZ" "CST") and similar tactics, but I think the localtime is determined once at startup and used thereafter. perhaps tzset() should be included in the newlisp base?



I could hard-code the offsets relative to my local timezone... but I may move this code around to different servers in different timezones.  And that would be laborious, maintaining the list of all timezones with their offsets.
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.

Lutz

#7
'date' takes a UTC number in seconds and returns a formatted string for local time. The minutes offset works well for me (why are you passing a quoted symbol?):


> (date (date-value)) ; executed at 1:20:04pm local time, (date-value) returned UTC
"Sat Oct 23 13:20:04 2010"
> (date (date-value) 60)
"Sat Oct 23 14:20:09 2010"
> (date (date-value) 120)
"Sat Oct 23 15:20:16 2010"
> (date (date-value) -60)
"Sat Oct 23 12:20:23 2010"
> (date (date-value) -120)
"Sat Oct 23 11:20:30 2010"
>


all other date-xx functions and 'now' work in UTC for input and output.



To find the offset for your timezone use:


(now 0 -2) ; for offset minutes UTC (west +, east -)
(now 0 -1) ; daylight savings time flag on UNIX 1/0, +- minutes on Win32


The idea is, to always save and work with UTC, but display local time using 'date'. As an alternative to use the adjustment value in 'date' for displaying UTC, you could use the new 'date-list' which takes an UTC value and returns a list of: year month day minutes seconds day-of-year day-of week UTC numbers. Together with 'format', this could look like this:


> (format "%04d-%02d-%02d %02d:%02d UTC" (0 5 (date-list 0)))
"1970-01-01 00:00 UTC"
>


substitute the 0 in 'date-list' with any other UTC date value.

TedWalther

#8
Ok, that makes sense.



I'm working on a module to work with dates in the "julian day" format.  Would you consider having something like that in the base distribution?  No external libraries required.  It would take the output of (now) or (date-list), convert to a julian day, and convert julian days to julian or gregorian calendar dates.  also to and from unix timestamps.



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.

cormullion

#9
Good idea, but I wonder what would from-julian do with dates before 1970 or after 2030 if the OS wasn't supporting 64 bit dates...



There might be some code you can snaffle from my time-utilities.lsp FOOP experiment...