I am looking for a simple way to get the current days sincethe epoch. Most language's standard time library have a get-seconds function that returns the number of seconds since the epoch, thus the function is for example in scheme: (define (days-since-epoch) ((get-seconds) / (* 60 60 24))) But it seems that in haskell the standard definition for the time library will not give me seconds since the epoch. There is technically enough information in the CalendarTime structure to calculate it, but it is a pretty complicated algorithm. Not to mention the fact that it is the exact opposite of the algorithm used to get that information in the first place, so I'd like to not have to undo it and just get the seconds as they are. Thanks for the help -mike
the haskell 98 time library is horribly broken, if you are using ghc, you can deconstruct the time constructor which has an Integer containing the number of seconds since epoch... otherwise you can use epoch :: ClockTime epoch = toClockTime $ CalendarTime { ctYear = 1970, ctMonth = January, ctDay = 0, ctHour = 0, ctMin = 0, ctSec = 0, ctTZ = 0, ctPicosec = 0, ctWDay = undefined, ctYDay = undefined, ctTZName = undefined, ctIsDST = undefined} and TimeDiff, unfortunatly you have to condense the TimeDiff to seconds, which is unfeasable... we really should fix the Haskell time library. I propose adding: toRawTime :: ClockTime -> (Integer,Integer) fromRawTime :: (Integer,Integer) -> ClockTime where the integers are the number of seconds and picoseconds since epoch, these would be enough to make the time library useful. I dont supose this could be considered a typo in the haskell 98 report? it is an embarasing thing for a language to not be able to do... John On Fri, Jan 31, 2003 at 04:20:29PM -0500, Mike T. Machenry wrote:
I am looking for a simple way to get the current days sincethe epoch. Most language's standard time library have a get-seconds function that returns the number of seconds since the epoch, thus the function is for example in scheme:
(define (days-since-epoch) ((get-seconds) / (* 60 60 24)))
But it seems that in haskell the standard definition for the time library will not give me seconds since the epoch. There is technically enough information in the CalendarTime structure to calculate it, but it is a pretty complicated algorithm. Not to mention the fact that it is the exact opposite of the algorithm used to get that information in the first place, so I'd like to not have to undo it and just get the seconds as they are.
Thanks for the help -mike _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
-- --------------------------------------------------------------------------- John Meacham - California Institute of Technology, Alum. - john@foo.net ---------------------------------------------------------------------------
I've been running into similar problems, and I've also been pointed to the TimeExt library that George Russell was talking about. However, in the end, I had to implement something by myself. Much unfortunately though, my program relies on an undocumented feature of GHC's implementation of TimeDiff in the Time library. John's code illustrates TimeDiff's deficiencies perfectly: JM> the haskell 98 time library is horribly broken, if you are using ghc, JM> you can deconstruct the time constructor which has an Integer containing JM> the number of seconds since epoch... otherwise you can use JM> epoch :: ClockTime JM> epoch = toClockTime $ CalendarTime { ctYear = 1970, ctMonth = January, JM> ctDay = 0, ctHour = 0, ctMin = 0, ctSec = 0, ctTZ = 0, ctPicosec = 0, JM> ctWDay = undefined, ctYDay = undefined, ctTZName = undefined, ctIsDST = JM> undefined} JM> and TimeDiff, JM> unfortunatly you have to condense the TimeDiff to seconds, which is JM> unfeasable... Ha! After playing with this, I discovered that only the seconds were set and all other fields remained untouched. At least in ghc's implementation. Interestingly, TimeDiff derives Eq and Ord, but I'd better not ask for their implementation... There is also a more fundamental problem with the TimeDiff data type. While seconds, minutes, hours, and days are clearly specified amounts of time, the duration of a month or a year may vary depending on the reference point where the time difference is applied. My conclusion is that time differences really should be measured in seconds and picoseconds. type TimeDiff = (Integer, Integer) JM> we really should fix the Haskell time library. I propose adding: JM> toRawTime :: ClockTime -> (Integer,Integer) JM> fromRawTime :: (Integer,Integer) -> ClockTime JM> where the integers are the number of seconds and picoseconds since JM> epoch, these would be enough to make the time library useful. JM> I dont supose this could be considered a typo in the haskell 98 report? JM> it is an embarasing thing for a language to not be able to do... Hmm, this is underspecified! As another poster said, (pointing out http://cr.yp.to/libtai, but it is better to look at http://cr.yp.to/time.html, which has a discussion on UTC vs TAI vs UNIX time) the official source of time is TAI, so it is best to base a time library *on the number of TAI seconds since a reference date* (which is btw what the libtai is all about). For compatibility with UNIX time, "Arthur David Olson's popular time library uses an epoch of 1970-01-01 00:00:10 TAI" [http://cr.yp.to/proto/utctai.html]. So this mostly means that you need to set your system clock correctly:-) Hence, a suitable specification for JM> toRawTime :: ClockTime -> (Integer,Integer) could be number of seconds since reference point, given as a pair (full seconds, picoseconds). This function *may* involve a time zone calculation for those that do not run their system clock on TAI (or UTC). JM> fromRawTime :: (Integer,Integer) -> ClockTime with toRawTime . fromRawTime == id and fromRawTime . toRawTime ~~ id (the internal representation of ClockTime may have less precision, so the difference would be less than system dependent constant, which could also be supplied by the library) Given these two raw ingredients, everything else can be computed from that. In addition, it would be nice to have parsing functions for various time and date formats (which is what I ended up writing myself for the ISO8601 format). Cheers, -Peter
Peter Thiemann (Thu, Feb 06, 2003 at 12:40:14PM -0800):
John's code illustrates TimeDiff's deficiencies perfectly:
There is also a more fundamental problem with the TimeDiff data type. While seconds, minutes, hours, and days are clearly specified amounts of time, the duration of a month or a year may vary depending on the reference point where the time difference is applied.
What time takes a year - 365 or 366 days? There are leap years! What time takes a month - 28, 29, 30 or 31 days? A week takes 7 days. How long is a day - 86399, 86400 or 86401 seconds and how long is a hour - 3599, 3600 or 3601 seconds? There are leap seconds! A second is the basic amount of time.
My conclusion is that time differences really should be measured in seconds and picoseconds.
How do you measure 100 attoseconds?
type TimeDiff = (Integer, Integer)
More general is newtype TimeDiff = TimeDiff Rational deriving (Eq, Ord)
Hmm, this is underspecified! As another poster said, (pointing out http://cr.yp.to/libtai, but it is better to look at http://cr.yp.to/time.html, which has a discussion on UTC vs TAI vs UNIX time) the official source of time is TAI, so it is best to base a time library *on the number of TAI seconds since a reference date* (which is btw what the libtai is all about). For compatibility with UNIX time, "Arthur David Olson's popular time library uses an epoch of 1970-01-01 00:00:10 TAI" [http://cr.yp.to/proto/utctai.html]. So this mostly means that you need to set your system clock correctly:-)
No, you have to check for leap seconds. There is one in every few years.
Hence, a suitable specification for JM> toRawTime :: ClockTime -> (Integer,Integer) could be number of seconds since reference point, given as a pair (full seconds, picoseconds). This function *may* involve a time zone calculation for those that do not run their system clock on TAI (or UTC). JM> fromRawTime :: (Integer,Integer) -> ClockTime with toRawTime . fromRawTime == id and fromRawTime . toRawTime ~~ id (the internal representation of ClockTime may have less precision, so the difference would be less than system dependent constant, which could also be supplied by the library)
Given these two raw ingredients, everything else can be computed from that. In addition, it would be nice to have parsing functions for various time and date formats (which is what I ended up writing myself for the ISO8601 format).
Cheers, -- Stefan Karrmann
"Stefan" == Stefan Karrmann <sk@mathematik.uni-ulm.de> writes:
Stefan> Peter Thiemann (Thu, Feb 06, 2003 at 12:40:14PM -0800): >> John's code illustrates TimeDiff's deficiencies perfectly: >> >> There is also a more fundamental problem with the TimeDiff data >> type. While seconds, minutes, hours, and days are clearly specified >> amounts of time, the duration of a month or a year may vary depending >> on the reference point where the time difference is applied. Stefan> What time takes a year - 365 or 366 days? There are leap years! Stefan> What time takes a month - 28, 29, 30 or 31 days? Stefan> A week takes 7 days. Stefan> How long is a day - 86399, 86400 or 86401 seconds and how long is a Stefan> hour - 3599, 3600 or 3601 seconds? There are leap seconds! Stefan> A second is the basic amount of time. Minutes, hours, and days (even weeks) are also well defined in terms of seconds. But not months and years. >> My conclusion is that time differences really should be measured in >> seconds and picoseconds. Stefan> How do you measure 100 attoseconds? >> type TimeDiff = (Integer, Integer) Stefan> More general is Stefan> newtype TimeDiff = TimeDiff Rational Stefan> deriving (Eq, Ord) I agree, I just was not bold enough to propose this :-) However, this seems to be close to the limit of the measurable, and I'm wondering how much precision is required in practice. >> Hmm, this is underspecified! >> As another poster said, (pointing out http://cr.yp.to/libtai, but it >> is better to look at http://cr.yp.to/time.html, which has a discussion >> on UTC vs TAI vs UNIX time) the official source of time is TAI, so it >> is best to base a time library >> *on the number of TAI seconds since a reference date* >> (which is btw what the libtai is all about). >> For compatibility with UNIX time, "Arthur David Olson's popular time >> library uses an epoch of 1970-01-01 00:00:10 TAI" >> [http://cr.yp.to/proto/utctai.html]. >> So this mostly means that you need to set your system clock correctly:-) Stefan> No, you have to check for leap seconds. There is one in Stefan> every few years. I do not understand this comment. All I am saying is that you should set your system clock to the number of seconds since the epoch. Leap seconds only come into play when converting to UTC. -- Peter Thiemann, Prof. Dr. Institut für Informatik, Universität Freiburg, Germany http://www.informatik.uni-freiburg.de/~thiemann
Peter Thiemann (Mon, Feb 10, 2003 at 04:36:17PM -0800):
"Stefan" == Stefan Karrmann <sk@mathematik.uni-ulm.de> writes:
Stefan> Peter Thiemann (Thu, Feb 06, 2003 at 12:40:14PM -0800): >> John's code illustrates TimeDiff's deficiencies perfectly: >> >> There is also a more fundamental problem with the TimeDiff data >> type. While seconds, minutes, hours, and days are clearly specified >> amounts of time, the duration of a month or a year may vary depending >> on the reference point where the time difference is applied.
Stefan> What time takes a year - 365 or 366 days? There are leap years! Stefan> What time takes a month - 28, 29, 30 or 31 days? Stefan> A week takes 7 days. Stefan> How long is a day - 86399, 86400 or 86401 seconds and how long is a Stefan> hour - 3599, 3600 or 3601 seconds? There are leap seconds! Stefan> A second is the basic amount of time.
Minutes, hours, and days (even weeks) are also well defined in terms of seconds. But not months and years.
No! There are leap seconds which let some minute contain exactly 61 or 59 seconds! Thus, you have a different fixed scales. The elements of each scale are given by a FIXED number of the first element.: 1. Seconds (SI-unit), kilo seconds, etc. 2. Minute, hours, days, weaks 3. Months, years, decades, centuries, ages, etc.
>> My conclusion is that time differences really should be measured in >> seconds and picoseconds.
Stefan> How do you measure 100 attoseconds?
1 attoseconds (1E-18 seconds) is a lot smaller then 1 picosecond.
>> type TimeDiff = (Integer, Integer)
Should (x,y) :: TimeDiff mean the fractional x/y ? If you still intend x to be seconds and y to be picoseconds you cannot represent attoseconds .
Stefan> More general is
Stefan> newtype TimeDiff = TimeDiff Rational Stefan> deriving (Eq, Ord)
I agree, I just was not bold enough to propose this :-) However, this seems to be close to the limit of the measurable, and I'm wondering how much precision is required in practice.
Here you are right. But if your calculations takes the same precision adding rationals is cheap.
>> Hmm, this is underspecified! >> As another poster said, (pointing out http://cr.yp.to/libtai, but it >> is better to look at http://cr.yp.to/time.html, which has a discussion >> on UTC vs TAI vs UNIX time) the official source of time is TAI, so it >> is best to base a time library >> *on the number of TAI seconds since a reference date* >> (which is btw what the libtai is all about). >> For compatibility with UNIX time, "Arthur David Olson's popular time >> library uses an epoch of 1970-01-01 00:00:10 TAI" >> [http://cr.yp.to/proto/utctai.html]. >> So this mostly means that you need to set your system clock correctly:-)
Stefan> No, you have to check for leap seconds. There is one in Stefan> every few years.
I do not understand this comment. All I am saying is that you should set your system clock to the number of seconds since the epoch. Leap seconds only come into play when converting to UTC.
-- Peter Thiemann, Prof. Dr. Institut für Informatik, Universität Freiburg, Germany http://www.informatik.uni-freiburg.de/~thiemann _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
-- Stefan Karrmann
participants (4)
-
John Meacham -
Mike T. Machenry -
Peter Thiemann -
Stefan Karrmann