Re: time since the epoch

2003-11-13 Thread Stefan Karrmann
Dear Juanma,

thanks for your remarks.

Juanma Barranquero (Mon, Nov 10, 2003 at 10:54:22AM +0100):
 On Fri, 7 Nov 2003 19:55:47 +0100
 Stefan Karrmann [EMAIL PROTECTED] wrote:
 
  I've inserted 'convert = (uncurry cFromTai) . cToTai'.
 
 Great, thanks.
 
  A fixed and checked version is appended and carbon copied to  
  [EMAIL PROTECTED]. 
 
 What's haskell-libs-developers? I thought libraries' development was
 carried over on [EMAIL PROTECTED] (And shouldn't we be discussing
 Tai.lhs there, BTW :)

Well, the original thread was on this list. I'm moving it to
[EMAIL PROTECTED] now.

 I'm attaching a patch (diff -u2) with a few small changes:

I've included it.

 More coments:
 
  - I'm sending you the patch throw the Haskell list because previous
attempts of sending to your e-mail address failed.

I'm using ASK as a spam killer. Do you have problems with it?

  - Are you very fond of the literate style? I ask because unlit'ing it
would allow adding Haddock coments, which would be nice.

I've given it a try, but my comment marking could be improved.

  - I'm not sure I like depending on a leapseconds table hardcoded in the
source, even if it changes slowly. Wouldn't it be better to have the
data in a file and load it through unsafePerformIO? (And isn't
loading configuration data one of the few good examples of use of
unsafePerformIO, after all? :)

Well, I included the two as examples. The empty one is correct for all
times before 1970-01-01. That's more than ten billion years.

  - I get a warning with -Wall:
 
 Warning: Defined but not used:
TimeDiff, days_from_MJD2unixEpoch, days_from_unixEpoch2MJD',
hours_per_day, isodelta, isomoveDHM, isomoveS, isomoveYM,
libtaiEpoch, month_per_year, test, test2

Some values are only for testing and debugging while others are
experimental, e.g. TimeDiff and friends.

Several of these are neither used nor exported. ???

Regards,
-- 
Stefan Karrmann
Bitte bzip2 benutzen!
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: time since the epoch

2003-11-10 Thread Juanma Barranquero
On Fri, 7 Nov 2003 19:55:47 +0100
Stefan Karrmann [EMAIL PROTECTED] wrote:

 I've inserted 'convert = (uncurry cFromTai) . cToTai'.

Great, thanks.

 A fixed and checked version is appended and carbon copied to  
 [EMAIL PROTECTED]. 

What's haskell-libs-developers? I thought libraries' development was
carried over on [EMAIL PROTECTED] (And shouldn't we be discussing
Tai.lhs there, BTW :)

I'm attaching a patch (diff -u2) with a few small changes:

 - 1%seconds_per_day  -  1 % seconds_per_day  (otherwise GHC complains
   in -fglasgow-exts mode because it misinterprets it as an implicit
   parameter).

 - I've put a few _ here and there to silence warnings for unused
   arguments.

 - I've renamed a few variables because of shadows an existing binding
   warnings.

 - I've deleted a few internal definitions apparently not used
   (according to -Wall), like cumulated_month_length_after_february.

 - I've corrected a few typos.

More coments:

 - I'm sending you the patch throw the Haskell list because previous
   attempts of sending to your e-mail address failed.

 - Are you very fond of the literate style? I ask because unlit'ing it
   would allow adding Haddock coments, which would be nice.

 - I'm not sure I like depending on a leapseconds table hardcoded in the
   source, even if it changes slowly. Wouldn't it be better to have the
   data in a file and load it through unsafePerformIO? (And isn't
   loading configuration data one of the few good examples of use of
   unsafePerformIO, after all? :)

 - I get a warning with -Wall:

Warning: Defined but not used:
 TimeDiff, days_from_MJD2unixEpoch, days_from_unixEpoch2MJD',
 hours_per_day, isodelta, isomoveDHM, isomoveS, isomoveYM,
 libtaiEpoch, month_per_year, test, test2

   Several of these are neither used nor exported. ???

Thanks,


Juanma



Tai.lhs.diff.bz2
Description: Binary data
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: time since the epoch

2003-11-07 Thread Stefan Karrmann
Dear Juanma, 
 
some last moment changes broke the library, I am sorry.  
 
Juanma Barranquero (Thu, Nov 06, 2003 at 05:03:03PM +0100): 
  
 On Sat, 1 Nov 2003 17:36:11 +0100 
 Stefan Karrmann [EMAIL PROTECTED] wrote:  
  
  a while ago time calculation was subject on this list. 
  Now, I have a time library based on the TAI (international 
  atomic time) time scale.  
  
 I get the following error with GHCi: 
  
  
  
 Compiling Main ( Tai.lhs, interpreted ) 
  
 Tai.lhs:450: 
 Couldn't match `LeapSeconds' against `TAI' 
 
 Also, wouldn't make sense to add:
 
 cConvert :: (Calendar a, Calendar b) = a - b
 cConvert = cFromTai . cToTai

I've inserted 'convert = (uncurry cFromTai) . cToTai'.

A fixed and checked version is appended and carbon copied to  
[EMAIL PROTECTED]. 
 
Regards, 
--  
Stefan Karrmann 



Tai.lhs.bz2
Description: Binary data
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: time since the epoch

2003-11-06 Thread Juanma Barranquero

On Sat, 1 Nov 2003 17:36:11 +0100
Stefan Karrmann [EMAIL PROTECTED] wrote:

 a while ago time calculation was subject on this list.
 Now, I have a time library based on the TAI (international
 atomic time) time scale.

I get the following error with GHCi:



Compiling Main ( Tai.lhs, interpreted )

Tai.lhs:450:
Couldn't match `LeapSeconds' against `TAI'
Expected type: LeapSeconds
Inferred type: TAI
In the first argument of `cFromTai', namely `taileap1'
In the first argument of `cSecond', namely
`(cFromTai taileap1 lst)'

Tai.lhs:453:
Couldn't match `LeapSeconds' against `TAI'
Expected type: LeapSeconds
Inferred type: TAI
In the first argument of `cFromTai', namely `taileap2'
In the first argument of `cSecond', namely
`(cFromTai taileap2 lst)'

Tai.lhs:472:
Couldn't match `LeapSeconds' against `TAI'
Expected type: LeapSeconds
Inferred type: TAI
In the first argument of `cFromTai', namely `taileap1'
In the first argument of `cSecond', namely
`(cFromTai taileap1 lst)'

Tai.lhs:475:
Couldn't match `LeapSeconds' against `TAI'
Expected type: LeapSeconds
Inferred type: TAI
In the first argument of `cFromTai', namely `taileap2'
In the first argument of `cSecond', namely
`(cFromTai taileap2 lst)'
Failed, modules loaded: none.



Also, wouldn't make sense to add:

cConvert :: (Calendar a, Calendar b) = a - b
cConvert = cFromTai . cToTai

Or it is already there and I've missed it?

Juanma


___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: time since the epoch

2003-11-03 Thread ketil+haskell
Stefan Karrmann [EMAIL PROTECTED] writes:

 a while ago time calculation was subject on this list.
 Now, I have a time library based on the TAI (international
 atomic time) time scale.

This is cool!  But what actually happens when people post interesting
library code to the list?  Does somebody snarf it, and put it in a
more convenient place?

Why not upload it into the Haskell library site at Sourceforge, and
just post a description and a pointer?

http://sourceforge.net/projects/haskell-libs/

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: time since the epoch

2003-11-02 Thread Stefan Karrmann
Hi,

a while ago time calculation was subject on this list.
Now, I have a time library based on the TAI (international
atomic time) time scale.

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.

 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:-)

Sincerly,
-- 
Stefan Karrmann
2003 Copyright (C) Stefan Karrmann [EMAIL PROTECTED]
All rights reserved.
The rights of the GNU Library General Public Licence Version 2
are granted, for details confer http://www.fsf.org/copyleft/lgpl.html.

This module provides data structures and functions to calculate with
Temps Atomique International (International Atomic Time, short TAI).
For further information about time see, e.g.
http://www.boulder.nist.gov/timefreq/general/glossary3.htm.

 module Main
 (
   --main,
   TAI(TAI)   -- Temps atomique international
   ,TAIDiff(TAIDiff)
   ,taidelta  -- TAI - TAI - TAIDiff
   ,taimove   -- TAI - TAIDiff - TAI
   ,taiadd-- TAIDiff - TAIDiff - TAIDiff
   ,taisub-- TAIDiff - TAIDiff - TAIDiff
   ,taimult   -- Rational - TAIDiff - TAIDiff
   ,taipow-- Integer  - TAIDiff - TAIDiff
   ,tainegate -- TAIDiff - TAIDiff
   ,tairecip  -- TAIDiff - TAIDiff
   ,unixEpoch -- TAI
   ,LeapSeconds(LeapSeconds)
   ,emptyLeaps-- LeapSeconds table valid until ISO 1970-01-01
   ,leaps_2002_06_01  -- LeapSeconds table valid until ISO 2002-06-01
   ,UTC(UTC)
   ,tai2utc   -- LeapSeconds - TAI - UTC
   ,utc2tai   -- UTC - TAI
   ,MJD(MJD)  -- Modified Julian Date
   ,utc2mjd   -- UTC - MJD
   ,mjd2utc   -- MJD - UTC
   ,JD(JD)-- Julian Date
   ,mjd2jd-- MJD - JD
   ,jd2mjd-- JD  - MJD
   ,ISO
   ,mjd2iso   -- MJD - ISO
   ,iso2mjd   -- ISO - MJD
 )
 where

 import Prelude
 import List
 import Ratio

Values of TAIDiff contains (fractional) seconds without
a reference point.

 newtype TAIDiff = TAIDiff Rational
 deriving (Eq,Ord,Show,Read)

This belongs almost to the class Num, but multiplication
does not make sense - you would get square seconds. Thus,
we have to define our own functions until
class (UnitRing r, Group a)  = Modul a
enters Haskell.

 taidelta (TAI r1) (TAI r2) = TAIDiff (r1 - r2)
 taimove (TAI r1) (TAIDiff r2) = TAI (r1 + r2)
 taiadd (TAIDiff r1) (TAIDiff r2) = TAIDiff (r1 + r2)
 taisub (TAIDiff r1) (TAIDiff r2) = TAIDiff (r1 - r2)
 taimult r1 (TAIDiff r2) = TAIDiff (r1 * r2)
 taipow i (TAIDiff r) = TAIDiff (r ^^ i)
 tainegate (TAIDiff r) = TAIDiff (- r)
 tairecip (TAIDiff r) = TAIDiff (1/r)

Values of TAI are fixed points on the time axis of the eigentime
of the standardisation organisation in our space-time universe.

 newtype TAI = TAI Rational
 deriving (Eq,Ord,Show,Read)
 untai (TAI r) = r

The first defined TAI value - UNIX(TM) epoch, i.e.
Thursday ISO 1970-01-01T00:00:00

 unixEpoch = TAI 10
   -- == ISO 1970 01 01 0 0 0 emptyLeaps
 libtaiEpoch = 4611686018427387914 -- 2^62 + 10

The leap second table data structure

 data LeapSeconds = LeapSeconds
TAI{- valid until -}
[(TAI, {- when -}
  Bool {- It is additional. -}
)]
  deriving (Eq,Show,Read)

Valid leap second table for all times before unix epoch.

 emptyLeaps = LeapSeconds unixEpoch []

Up to date leap seconds can be found at some official sources:
http://maia.usno.navy.mil/leapsec.html
http://hpiers.obspm.fr/webiers/general/earthor/utc/UTC.html

 leaps_2002_06_01 =
   let
  valid = utc2tai $ mjd2utc $ iso2mjd $ ISO 2002 06 01 23 59 59 lst
  lst@(LeapSeconds _ ls) =
 h 1998 12 31 True
 $ h 1997 06 30 True
 $ h 1995 12 31 True
 $ h 1994 06 30 True
 $ h 1993 06 30 True
 $ h 1992 06 30 True
 $ h 1990 12 31 True
 $ h 1989 12 31 True
 $ h 1987 12 31 True
 $ h 1985 06 30 True
 $ h 1983 06 30 True
 $ h 1982 06 30 True
 $ h 1981 06 30 True
 $ h 1979 12 31 True

[OT] Re: time since the epoch

2003-02-25 Thread Stefan Karrmann
Peter Thiemann (Mon, Feb 10, 2003 at 04:36:17PM -0800):
  Stefan == Stefan Karrmann [EMAIL PROTECTED] 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
 Stefanderiving (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
 [EMAIL PROTECTED]
 http://www.haskell.org/mailman/listinfo/haskell

-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Time since the epoch

2003-02-12 Thread Jonathan Coxhead
On 11 Feb 2003, at 18:23, George Russell wrote:

 Add 1 month to 1st February 2003.  This produces 1st March 2003.  (with no
 overflow.)

   Here, you add 28 days, which is the number of days in (this) February. Fair 
enough.

 Add 1 month to 31st January 2003.  Then we get 31st February 2003.  This 
clearly
 requires an overflow; we note that February 2003 has 28 days, and so roll over
 to 3rd March 2003.

   Here, you add 31 days, which is the number of days in January. Also fair 
enough.

 Note that in this case Add 1 month is not a monotonic operation. 

 Add 1 minute to 23:59:60 31st December 2003.  I assume that this is a valid 
time
 and that it will be a leap second; if not choose some other year.
 
 This is complicated since we have multiple overflows.  First stage you get the
 invalid time
 
 23:60:60 31st December 2003.

   But **HERE**, you add 60 seconds. Why? If you want to add 1 minute to 
23:59:60 31st December 2003, and assuming still that it is a leap minute, then 
to be consistent with the rule for months, I think you ought to add **61** 
seconds---the number of seconds in *this* minute.

   If the problem had been to add 60 seconds, I would agree, but if the 
problem is to add 1 minute, I think there's a flaw here.

/|
 . . . (_|/ o n a t h a n
/|
   (_/
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: Time since the epoch

2003-02-12 Thread Peter Thiemann
George So while I started typing this thinking it was a straight
George choice between Peter's monotonicity/invertibility and the
George fact that my system corresponds better to natural usage,
George Peter doesn't even have monotonicity or invertibility. 

Yes, I also realized that after I left my office.
Sorry for the confusion.

...

Now, isn't that a good argument for just *defining* the length of
a year and a month in terms of seconds and then go with it. It
naturally gives you all nice properties and you cannot argue if and
when you want to overflow or underflow or whatever? 

-Peter

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: Time since the epoch

2003-02-12 Thread George Russell
Jonathan Coxhead wrote (quoting me, snipped)

Add 1 minute to 23:59:60 31st December 2003.  I assume that this is a valid 
time

and that it will be a leap second; if not choose some other year.

This is complicated since we have multiple overflows.  First stage you get the
invalid time

23:60:60 31st December 2003.


   But **HERE**, you add 60 seconds. Why? If you want to add 1 minute to 
23:59:60 31st December 2003, and assuming still that it is a leap minute, then 
to be consistent with the rule for months, I think you ought to add **61** 
seconds---the number of seconds in *this* minute.

   If the problem had been to add 60 seconds, I would agree, but if the 
problem is to add 1 minute, I think there's a flaw here.

Your arithmetic is faulty.  Because we are assuming 23:59:60 31st December 2003
is a leap second, there are 61 seconds until 00:01:00 1st January 2004, the time
my method (eventually) produces.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



RE: time since the epoch

2003-02-11 Thread Simon Marlow
[snip]
 It is always a problem to lump things with different semantics into
 the same type :-) What I'm arguing is that there should be only one
 fixed-duration offset datatype and it should be in terms of (seconds,
 picoseconds).
 Other fixed durations can be easily defined in terms of this
 datatype. 
 I'm still not sure that you actually want base-dependent offsets, but
 again they can be easily defined on top of the fixed duration
 datatype. And they should be specified separately from the base
 functionality.
[snip]

I wrote a reply, but I don't really have anything new to say over what's
been said already, so I'll keep it brief instead.  The copy of ISO8601
that I looked at is here:
http://www.astroclark.freeserve.co.uk/iso8601/index.htm, but from what
you said I'm guessing you're looking at a different version.

Anyway, to sum up: 

  - I agree that there should be a constant-duration time offset type.
However, TimeDiff does actually fuction perfectly well as one at
the moment, since diffClockTimes only fills in the seconds and
picoseconds fields.

  - I believe a reasonable interpretation of the other fields of
TimeDiff is as base-dependent offsets.  The current implementation 
in GHC doesn't do this, but you can use TimeExts which does.

  - Our implementation of ClockTime uses C's gettimeofday(), which
apparently is based a broken definition of the epoch.  Oh well :-)

Cheers,
Simon
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: Time since the epoch

2003-02-11 Thread George Russell
Peter wrote (snipped)
 As far as I read ISO8601 (which also has a notation for durations)
 this is unspecifed :-) And as far as I read TimeExts.lhs it does some
 sort of rollover. My take would be to specify the behavior for adding
 something like a TimeDiff to a base date in a consistent manner and
 then cast that in stone. If there is a (reasonable) standard for this
 kind of calculation, then this should be the basis for the specification.
OK, what TimeExts does, I hope, is add the appropriate amount of the appropriate
time unit (whatever it is) directly, then rely on the CalendarTime conversions to
resolve any overflows.  This probably isn't very clear,
so I'll give some examples of what I think ought to happen.

Add 1 month to 1st February 2003.  This produces 1st March 2003.  (with no overflow.)

Add 1 month to 31st January 2003.  Then we get 31st February 2003.  This clearly 
requires
an overflow; we note that February 2003 has 28 days, and so roll over to 3rd March 
2003.

Note that in this case Add 1 month is not a monotonic operation. 

Add 1 minute to 23:59:60 31st December 2003.  I assume that this is a valid time and 
that it
will be a leap second; if not choose some other year.

This is complicated since we have multiple overflows.  First stage you get the invalid 
time

23:60:60 31st December 2003.  I don't know what TimeExts (or rather the CalendarTime 
conversions)
do in this case, but what I think they *ought* to do is work from the most significant 
unit down,
rolling around to produce a significant date at each time.  When we roll around, we 
have to bump the
next unit, and iterate.

So:
2003 OK.
2003 December OK.
2003 December 31st OK.
2003 December 31st 23 OK.
2003 December 31st 23:60 NOT OK.  We bump the next unit and subtract this one, then we 
have to iterate
   from the top down.   So we replace 23:60 by 24:00.
   and get
2003 December 31st 24
   not OK.  Replaces 31st 24 by 32nd 00.
2003 December 32nd 
   not OK
2003 Unidecimber (13th month) 1st
   not OK
2004 January OK
2004 January 1st OK
2004 January 1st 00 OK
2004 January 1st 00:00 OK
2004 January 1st 00:00:60 Not OK.
   Replace 00:60 by 01:00 and you eventually get
2004 January 1st 00:01:00
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-11 Thread Peter Thiemann
 Stefan == Stefan Karrmann [EMAIL PROTECTED] 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
Stefanderiving (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
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-11 Thread Peter Thiemann

SM I wrote a reply, but I don't really have anything new to say over what's
SM been said already, so I'll keep it brief instead.  The copy of ISO8601
SM that I looked at is here:
SM http://www.astroclark.freeserve.co.uk/iso8601/index.htm, but from what
SM you said I'm guessing you're looking at a different version.

Oops, I guess I did. However, the 2000 version does not clarify
matters much more. It does, however, make the distinction between day
(= 24 hours) and calendar day (period until the same daytime is
reached again). Regarding, time periods it only specifies the syntax,
not the semantics. Oh well.

SM Anyway, to sum up: 

SM   - I agree that there should be a constant-duration time offset type.
SM However, TimeDiff does actually fuction perfectly well as one at
SM the moment, since diffClockTimes only fills in the seconds and
SM picoseconds fields.

Ok. But there is the caveat that 
TimeDiff { ... tdSec :: Int ... }
which will give rise to overflows in a few years.

SM   - I believe a reasonable interpretation of the other fields of
SM TimeDiff is as base-dependent offsets.  The current implementation 
SM in GHC doesn't do this, but you can use TimeExts which
SM does.

In addition, it does not muddle months, years, etc together into one
TimeDiff value. This is a GOOD THING because you would have to specify
the sequence in which the various items are added to the reference to
get a well-defined behavior.

SM   - Our implementation of ClockTime uses C's gettimeofday(), which
SM apparently is based a broken definition of the epoch.  Oh well :-)

IMHO, the TimeDiff data type is the source of all evil (in Time, at
least). What about the following proposal for extending TimeExts: 
* Add a datatype
  data Duration = Duration Integer Integer
* Define the operations
  addToClockTime :: Duration - ClockTime - ClockTime
  diffClockTimes :: ClockTime - ClockTime - Duration
  [[ and deprecate using them from Time ]]
* Write an explicit specification for the remaining operators.

This should not be much effort. [the overall goal being, of course, to
phase out the Time module]

For further cleanup, the stuff dealing with CalendarTime could be
moved into its own module Calendar. And it would be very useful to
have parsing functions like 
parseTime :: String - CalendarTime
[might have to be IO CalendarTime because the interpretation depends
on the local time zone, etc]

Cheers
-Peter
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: Time since the epoch

2003-02-11 Thread Peter Thiemann
George OK, what TimeExts does, I hope, is add the appropriate amount of the 
appropriate
George time unit (whatever it is) directly, then rely on the CalendarTime 
conversions to
George resolve any overflows.  This probably isn't very clear,
George so I'll give some examples of what I think ought to
George happen.

I see. You propose to always add the duration of the current
entity. IE, a month rooted in January has 31 days, and a year rooted
in a leap year has 366 days. How do you define subtraction, given that
your addition is not monotonic and that you (probably) want addition
and subtraction be inverses?

Actually, you could equally well argue that you should always take the
duration of the next following entity (in seconds, but I won't go into
that detail). While this means that  (in a non-leap year)
January 1 + 1 month = January 29
it preserves monotonicity:
January 31 + 1 month = February 28
so that you could define subtraction (although at some expense).

George Add 1 month to 1st February 2003.  This produces 1st March 2003.  (with no 
overflow.)

George Add 1 month to 31st January 2003.  Then we get 31st February 2003.  This 
clearly requires
George an overflow; we note that February 2003 has 28 days, and so roll over to 
3rd March 2003.

George Note that in this case Add 1 month is not a monotonic operation. 

George Add 1 minute to 23:59:60 31st December 2003.  I assume
George that this is a valid time and that it 
George will be a leap second; if not choose some other year.

[... long calculation ...]

George 2004 January 1st 00:01:00

I would argue that adding one minute might be interpreted either
* as an absolute minute (add 60 seconds)
* or as the duration of the next calendar minute (which happens to be
  60 seconds, too).
(both resulting in 00:00:59)

In any case, it is merely a matter of interpreting the amount in terms
of seconds, and then let the translation inside of calendartime do its
work for you. 

-Peter
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: Time since the epoch

2003-02-11 Thread George Russell
Peter Thiemann wrote:
 
 George OK, what TimeExts does, I hope, is add the appropriate amount of the 
appropriate
 George time unit (whatever it is) directly, then rely on the CalendarTime 
conversions to
 George resolve any overflows.  This probably isn't very clear,
 George so I'll give some examples of what I think ought to
 George happen.
 
 I see. You propose to always add the duration of the current
 entity. IE, a month rooted in January has 31 days, and a year rooted
 in a leap year has 366 days. How do you define subtraction, given that
 your addition is not monotonic and that you (probably) want addition
 and subtraction be inverses?
I would drop the requirement that addition and subtraction be inverse, and
use exactly the same procedure only with changes of sign.  So first adjust the date,
then roll.

 
 Actually, you could equally well argue that you should always take the
 duration of the next following entity (in seconds, but I won't go into
 that detail). While this means that  (in a non-leap year)
 January 1 + 1 month = January 29
 it preserves monotonicity:
 January 31 + 1 month = February 28
 so that you could define subtraction (although at some expense).
[snip]
Well I don't see much point in arguing this at length, since this is one case where it 
doesn't
really matter what we do so long as we do something.   HOWEVER I will make some brief 
points
and then leave it to other Haskellers to argue about.

Here are some specific objections.
(1) Peter's notion of addition is odd.  I can't believe anyone but Peter would say 
that the date
1 month from 1st January is 29th January in a non-leap year, or 30th January in a leap 
year.
(2) Peter's notion of subtraction is worse.  True, it's
inverse to addition, but that's all it's good for.  For example, if you ask What 
happens
if you subtract 1 month from 1st February?, then Peter's method gives you 4th 
January in a normal
year, or 3rd January in a leap year.  I can't believe if you were to ask someone on 
the street
What date is 1 month before 1st February? they would give you that answer.
(3) Both are fundamentally asymmetric.  What happens for example when you add (-1) 
months?
Do you subtract the length of the previous month?  This is nice and symmetrical.  Or 
do you
subtract the length of this month?  This is not symmetrical, but means that it is the 
same
as subtracting 1 month.

However there's an ever better objection which has just occurred to me.  Peter's 
notion of
subtraction is UNDEFINED.  For, what is 29th January MINUS 1 month?  As he says, in 
his system.

January 1 + 1 month = January 29

but of course it is also true that

December 29 + 1 month = January 29.

Even worse, December 30 + 1 month = January 30th, so you don't have monotonicity 
either.

So while I started typing this thinking it was a straight choice between Peter's 
monotonicity/invertibility
and the fact that my system corresponds better to natural usage, Peter doesn't even 
have 
monotonicity or invertibility.  So I think my method wins.  Nyaaa.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-10 Thread Peter Thiemann

SM TimeDiff isn't a duration, it's a way of specifying time offsets whose
SM duration depends on the base to which the offset is being added.  If we
SM only had constant-duration offsets, then there would be no way to say
SM give me a ClockTime for this time next Wednesday.

[nitpicking] Oops, this is not the purpose stated in the library report:
The TimeDiff type records the difference between two clock times in a
user-readable way. 

Anyway, the sort of specification that you are talking about is really
a pain IMHO. Actually, you could not use TimeDiff to state it,
either. [ISO8601 allows it but I think it's too imprecise to be useful]

SM The problem is really that all the different kinds of offset are lumped
SM into one type: there ought to be a TimeDiffSeconds, TimeDiffMonths, and
SM so on.  TimeDiffSeconds is a constant-duration offset, but
SM TimeDiffMonths isn't.  The problem with lumping them into one type is
SM that if multiple components are non-zero, you don't know in which order
SM to add them.

It is always a problem to lump things with different semantics into
the same type :-) What I'm arguing is that there should be only one
fixed-duration offset datatype and it should be in terms of (seconds,
picoseconds).
Other fixed durations can be easily defined in terms of this
datatype. 
I'm still not sure that you actually want base-dependent offsets, but
again they can be easily defined on top of the fixed duration
datatype. And they should be specified separately from the base
functionality.

Certainly, differences between clock times should be in terms of the 
fixed-duration datatype. 

SM The TimeExts library gives you separate differences like
SM these, BTW.

That sounds good, I'll look at it again (it's pretty much bare code,
so I might have overlooked something).

 Unfortunately, with UTC, this goes on to make adding *anything* except
 seconds to certain ClockTimes (namely the instants of leap seconds,
 eg, what happens if you add 1 minute to 23:59:60 ? This is a perfectly
 legal UTC time on a day with a leap second) meaningless.

SM That's right, and here I'm not sure whether the right behaviour is to
SM raise an exception or to roll over to the next nearest date/time.  I
SM believe TimeExts does some kind of rolling over, but I'm not sure of the
SM exact semantics (George?).

As far as I read ISO8601 (which also has a notation for durations)
this is unspecifed :-) And as far as I read TimeExts.lhs it does some
sort of rollover. My take would be to specify the behavior for adding
something like a TimeDiff to a base date in a consistent manner and
then cast that in stone. If there is a (reasonable) standard for this
kind of calculation, then this should be the basis for the specification.

SM Ok, ISO8601 seems to specify only constant-duration time intervals, but
SM allows them to be given in terms of years, months, days etc., where a
SM month is specified to be 30 days, it seems, and similar
SM approximations

If I remember correctly, then ISO8601 specifies durations up to a day,
but bails out at months and years. 

 
 Agreed! So what is epoch? Is it
 Seconds since 00:00:00 on 1 Jan 1970 [TAI]?

SM I guess so... GHC's implementation will be whatever the C library uses,
SM which I assume is the one you specified above (at least on a decent
SM implementation).

Unfortunately, if you are using time(2), then you'll get rubbish (from
the manual page):

DESCRIPTION
   time  returns the time since the Epoch (00:00:00 UTC, Jan­
   uary 1, 1970), measured in seconds.
[...]
NOTES
   POSIX.1  defines  seconds since the Epoch as a value to be
   interpreted as the number of seconds between  a  specified
   time  and the Epoch, according to a formula for conversion
   from UTC equivalent to conversion on the naïve basis  that
   leap  seconds are ignored and all years divisible by 4 are
   leap years.  This value is not the same as the actual num­
   ber  of seconds between the time and the Epoch, because of
   leap seconds and because clocks are  not  required  to  be
   synchronised  to  a  standard reference.  The intention is
   that the interpretation of seconds since the Epoch  values
   be  consistent;  see  POSIX.1  Annex  B  2.2.2 for further
   rationale.

The problem is that this notion of time is discontinuous and sometimes
not strictly increasing. See the various references pointed out by
members of the list for why this can be a problem.

-Peter

PS, I see you are trying to follow-up to haskell-cafe, but I'm not
subscribed to that list.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-10 Thread Stefan Karrmann
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
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-10 Thread Stefan Karrmann
Peter Thiemann (Fri, Feb 07, 2003 at 10:22:12AM -0800):
  SM == Simon Marlow [EMAIL PROTECTED] writes:
 SM This isn't a problem with the spec, I think.  A TimeDiff of 1 month is
 SM precisely a difference, which, when added to a given ClockTime, produces
 SM a ClockTime which is one month later (with respect to some timezone,
 SM presumably UTC since it isn't specified otherwise).  That is, January
 SM 12th 12:00 UTC becomes February 12th 12:00 UTC, and so on.  Adding one
 SM month to certain ClockTimes is meaningless: eg. adding one month to
 SM January 31st doesn't work.
 
 Unfortunately, with UTC, this goes on to make adding *anything* except
 seconds to certain ClockTimes (namely the instants of leap seconds,
 eg, what happens if you add 1 minute to 23:59:60 ? This is a perfectly
 legal UTC time on a day with a leap second) meaningless. My take would
 be to look at an established standard for expressing time durations
 (eg, ISO8601) and just adhere to that (but not the POSIX standard,
 please!). Personally, I think that it is unacceptable to make
 something like addToClockTime a partial function.

IMHO, you need two different functions to add time. One that add the
absolute time difference (as TAI seconds). Another one add calendar
times and rounds down as needed, e.g.

(timediff calTime1 calTime2) :: TimeDiff (in years, months, etc.)

floorTimeAdd '2000-01-31' (Month 1) == '2000-02-28'
floorTimeAdd '2004-01-31' (Month 1) == '2000-02-29' -- a leap year

Suppose a leap second:
floorTimeAdd '2000-01-31.23:59:60' (Minute 1) == '2000-02-01.00:00:59'


Cheers,
-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



RE: time since the epoch

2003-02-10 Thread Simon Marlow
 SM TimeDiff has a perfectly well-defined meaning for Eq 
 and Ord: one
 SM TimeDiff is equal to another iff all the fields are 
 respectively equal.
 
 Yes, sure, Eq and Ord are defined by 
   deriving (Eq, Ord, ...)
 but this does not make much sense if the representation for a
 particular duration is not unique. All I'm asking for is a unique
 representation for a duration and I do not see how you can do this
 using not uniquely defined terms like month and year.

TimeDiff isn't a duration, it's a way of specifying time offsets whose
duration depends on the base to which the offset is being added.  If we
only had constant-duration offsets, then there would be no way to say
give me a ClockTime for this time next Wednesday.

The problem is really that all the different kinds of offset are lumped
into one type: there ought to be a TimeDiffSeconds, TimeDiffMonths, and
so on.  TimeDiffSeconds is a constant-duration offset, but
TimeDiffMonths isn't.  The problem with lumping them into one type is
that if multiple components are non-zero, you don't know in which order
to add them.

The TimeExts library gives you separate differences like these, BTW.

[snip]
 SM This isn't a problem with the spec, I think.  A 
 TimeDiff of 1 month is
 SM precisely a difference, which, when added to a given 
 ClockTime, produces
 SM a ClockTime which is one month later (with respect to 
 some timezone,
 SM presumably UTC since it isn't specified otherwise).  
 That is, January
 SM 12th 12:00 UTC becomes February 12th 12:00 UTC, and 
 so on.  Adding one
 SM month to certain ClockTimes is meaningless: eg. 
 adding one month to
 SM January 31st doesn't work.
 
 Unfortunately, with UTC, this goes on to make adding *anything* except
 seconds to certain ClockTimes (namely the instants of leap seconds,
 eg, what happens if you add 1 minute to 23:59:60 ? This is a perfectly
 legal UTC time on a day with a leap second) meaningless.

That's right, and here I'm not sure whether the right behaviour is to
raise an exception or to roll over to the next nearest date/time.  I
believe TimeExts does some kind of rolling over, but I'm not sure of the
exact semantics (George?).

 My take would
 be to look at an established standard for expressing time durations
 (eg, ISO8601) and just adhere to that (but not the POSIX standard,
 please!). Personally, I think that it is unacceptable to make
 something like addToClockTime a partial function.

Ok, ISO8601 seems to specify only constant-duration time intervals, but
allows them to be given in terms of years, months, days etc., where a
month is specified to be 30 days, it seems, and similar approximations
are made for the other units.  This seems very odd to me, but if that's
what you want...  (it's possible I'm misreading the standard, or maybe I
got hold of an old version though).

 SM At least, that's how I believe it is supposed to work.  GHC's
 SM implementation *is* completely wrong (which is 
 perhaps where some of the
 SM confusion comes from), but the TimeExts library can 
 be used instead of
 SM TimeDiffs.
 
 Well, so you agree that the behavior of the Time module is
 unspecified! Of course, I'm not blaming GHC's implementation which
 cannot be right under these circumstances.

Yes, it's unspecified, but I also think many people misinterpret it to
be more broken than it actually is.

 SM This is a perfectly reasonable definition of absolute 
 time, we don't
 SM need to talk about TAI at all, except to define what 
 the epoch means.
 
 Agreed! So what is epoch? Is it
 Seconds since 00:00:00 on 1 Jan 1970 [TAI]?

I guess so... GHC's implementation will be whatever the C library uses,
which I assume is the one you specified above (at least on a decent
implementation).

Cheers,
Simon
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe



Re: time since the epoch

2003-02-09 Thread Stefan Karrmann
Matthew Donadio (Fri, Feb 07, 2003 at 01:13:30PM -0500):
 Pretty much the whole world runs on UTC.  All of the common time
 distribution systems use UTC.  Technically, GPS doesn't, but the GPS
 signal includes the correction to UTC.  I understand the argument for
 using TAI.  Maybe internally the libray should use TAI, but default to
 giving the user UTC?

Yes, TAI should be the base to add seconds. (It's a total function!)
Two functions should connect it to UTC, e.g.:

taiutc :: UTCleaps - TAItime - (UTCtime, Bool {-isLeap-})
utctai :: UTCleaps - Bool {- isLeap -} - UTCtime - TAItime

where

newtype UTCleaps = UTCleaps ( [ (TAItime,Bool {- Skipped or Additional -}) ],
  TAItime {- valid (at least) until -} )
newtype UTCtime = UTCtime Rational

Note: o It is easy to use (utctai leaps False) and
(\t - first (taiutc leaps t)) as a simple interface.
  o Only, programs that run several month have to update the
leap-seconds table more than once.

On UTCtime we can build ISO, Gregorian, Julian, etc. calendars.


Cheers,
-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-07 Thread Stefan Karrmann
Keith Wansbrough (Thu, Feb 06, 2003 at 05:46:22PM +):
 Stefan Karrmann [EMAIL PROTECTED] writes:
 
  A sound base for a Time implementation should use TAI (temps atomique
  international), c.f. http://cr.yp.to/libtai.html.
 
 I disagree; I think UTC is quite sufficient, and will match the users'
 expectations much better.  (executive summary: UTC is the time on your
 watch (+/- timezone of course), TAI is behind by a few seconds, and
 this difference changes each time there's a new leap second).
 
 However, the reference above is not to TAI, but to a library called
 libtai.  I don't know anything about this; Stefan, maybe you could
 tell us some more?

One TAI second is defined as the duration of 9192631770 periods of the
radiation corresponding to the transition between the two hyperfine
levels of the ground state of the cesium atom (quoted from
http://cr.yp.to/libtai/tai64.html). Therefore, it is easy to add
seconds to a TAI-label. If you have a leap-second table, you can
easily convert TAI into UTC but not visa-versa (afaik), since in UTC
leap-seconds are mapped to the previous second! (You need a leap-flag.)
From UTC to CalenderTime (Gregorian (from 1582) or ISO time) is
straight forward.

Libtai is a public domain implementation of 64-bit TAI-labels, which
are defined from 1E+11 years before 1970 to 1E+11 years after 1970.
Thus this would avoid year 2038 and 2036 bugs of other common time
representations.

References (some may moved into nirwana):
1. http://www.boulder.nist.gov/timefreq/general/glossary3.htm
2. http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm
3. http://sadira.gb.nrao.edu/~rfisher/Ephemerides/times.html
4. http://purl.org/DC/elements/1.1/

Sincerly,
-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-07 Thread Matthew Donadio
Hi all,

I'm jumping into this a bit late, but I have some good info about time. 
Two sites that I know about that have good tutorials and white papers
are

http://www.datum.com/res_technical.html
http://www.truetime.com/DOCSn/TTreferencematerial.html

In particlar, the paper Timing and Time Code Reference Book is very
interesting.  It explains several different time standards that are
currently used, and tells you why UTC needs leap seconds.

Pretty much the whole world runs on UTC.  All of the common time
distribution systems use UTC.  Technically, GPS doesn't, but the GPS
signal includes the correction to UTC.  I understand the argument for
using TAI.  Maybe internally the libray should use TAI, but default to
giving the user UTC?

-- 
Matthew Donadio ([EMAIL PROTECTED])
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-07 Thread Glynn Clements

Matthew Donadio wrote:

 Pretty much the whole world runs on UTC.  All of the common time
 distribution systems use UTC.  Technically, GPS doesn't, but the GPS
 signal includes the correction to UTC.  I understand the argument for
 using TAI.  Maybe internally the libray should use TAI, but default to
 giving the user UTC?

I'd argue that the most important factor is compatibility with the
rest of the OS. If the underlying OS doesn't support leap seconds,
then nor should the Haskell environment.

IOW, the Haskell functions need to be wrappers around the
corresponding libc functions (or their Windows equivalents). I.e.:

Haskell C

getClockTimegettimeofday
toCalendarTime  localtime
toUTCTime   gmtime
toClockTime mktime

-- 
Glynn Clements [EMAIL PROTECTED]
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-07 Thread Peter Thiemann
 SM == Simon Marlow [EMAIL PROTECTED] writes:

 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...

SM TimeDiff has a perfectly well-defined meaning for Eq and Ord: one
SM TimeDiff is equal to another iff all the fields are respectively equal.

Yes, sure, Eq and Ord are defined by 
  deriving (Eq, Ord, ...)
but this does not make much sense if the representation for a
particular duration is not unique. All I'm asking for is a unique
representation for a duration and I do not see how you can do this
using not uniquely defined terms like month and year.
As an aside, you can easily define convenience functions that map your
(application's) idea of months and years to seconds, but it would be
much harder the other way round.

 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.

SM This isn't a problem with the spec, I think.  A TimeDiff of 1 month is
SM precisely a difference, which, when added to a given ClockTime, produces
SM a ClockTime which is one month later (with respect to some timezone,
SM presumably UTC since it isn't specified otherwise).  That is, January
SM 12th 12:00 UTC becomes February 12th 12:00 UTC, and so on.  Adding one
SM month to certain ClockTimes is meaningless: eg. adding one month to
SM January 31st doesn't work.

Unfortunately, with UTC, this goes on to make adding *anything* except
seconds to certain ClockTimes (namely the instants of leap seconds,
eg, what happens if you add 1 minute to 23:59:60 ? This is a perfectly
legal UTC time on a day with a leap second) meaningless. My take would
be to look at an established standard for expressing time durations
(eg, ISO8601) and just adhere to that (but not the POSIX standard,
please!). Personally, I think that it is unacceptable to make
something like addToClockTime a partial function.

SM At least, that's how I believe it is supposed to work.  GHC's
SM implementation *is* completely wrong (which is perhaps where some of the
SM confusion comes from), but the TimeExts library can be used instead of
SM TimeDiffs.

Well, so you agree that the behavior of the Time module is
unspecified! Of course, I'm not blaming GHC's implementation which
cannot be right under these circumstances.

 My conclusion is that time differences really should be measured in
 seconds and picoseconds. 
 
 type TimeDiff = (Integer, Integer)

SM We already have this kind of TimeDiff: just don't use anything except
SM the seconds and picoseconds fields.

Indeed, I found by experimentation that diffClockTimes only fills in
these two fields so that my attempt to compare the result with 
TimeDiff{ 0... tdDay = 14 ... 0 }
was doomed.

Unfortunately, the tdSec field has type Int, so its range is too small
to be useful.

SM I agree with John Meacham in that it ought to be possible to get a raw
SM time in terms of seconds/picoseconds since the epoch, and indeed GHC
SM lets you do that: importing System.Time lets you get at the
SM representation of ClockTime:

SM data ClockTime
SM   = TOD Integer -- Seconds since 00:00:00 on 1 Jan 1970
SM Integer -- Picoseconds with the specified second

SM This is a perfectly reasonable definition of absolute time, we don't
SM need to talk about TAI at all, except to define what the epoch means.

Agreed! So what is epoch? Is it
Seconds since 00:00:00 on 1 Jan 1970 [TAI]
?
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-06 Thread Stefan Karrmann
Simon Peyton-Jones (Mon, Feb 03, 2003 at 10:06:40AM -):
 
 | 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
 | 
 ...
 | 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...
 
 Meanwhile, I suspect there's an opportunity for someone (or a small
 group) to suggest a new Time library that really does the business, and
 provide an implementation.  If it's sufficiently persuasive, all the
 implementations will adopt it and it can become a de-facto standard.

A sound base for a Time implementation should use TAI (temps atomique
international), c.f. http://cr.yp.to/libtai.html.

 The implementation is important because Time is a weird enough thing
 that only an expert can implement the spec!  

-- 
Stefan Karrmann
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-06 Thread Keith Wansbrough
Stefan Karrmann [EMAIL PROTECTED] writes:

 A sound base for a Time implementation should use TAI (temps atomique
 international), c.f. http://cr.yp.to/libtai.html.

I disagree; I think UTC is quite sufficient, and will match the users'
expectations much better.  (executive summary: UTC is the time on your
watch (+/- timezone of course), TAI is behind by a few seconds, and
this difference changes each time there's a new leap second).

However, the reference above is not to TAI, but to a library called
libtai.  I don't know anything about this; Stefan, maybe you could
tell us some more?

--KW 8-)

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-06 Thread Matt Hellige
[Keith Wansbrough [EMAIL PROTECTED]]
 Stefan Karrmann [EMAIL PROTECTED] writes:
 
  A sound base for a Time implementation should use TAI (temps atomique
  international), c.f. http://cr.yp.to/libtai.html.
 
 I disagree; I think UTC is quite sufficient, and will match the users'
 expectations much better.  (executive summary: UTC is the time on your
 watch (+/- timezone of course), TAI is behind by a few seconds, and
 this difference changes each time there's a new leap second).
 
 However, the reference above is not to TAI, but to a library called
 libtai.  I don't know anything about this; Stefan, maybe you could
 tell us some more?
 

I know it's not really on topic, but for those of us who are ignorant
of the details of time standards, does anyone have a pointer to a
decent conceptual (i.e., non-software specific) overview of the
subject? Leap seconds, etc., are all pretty much new to me, but I am
curious.

Matt

-- 
Matt Hellige  [EMAIL PROTECTED]
http://matt.immute.net
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-02-06 Thread Peter Thiemann
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
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



RE: time since the epoch

2003-02-03 Thread Simon Peyton-Jones

| 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
| 
...
| 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...

Alas, no.  CUP is, even as I type, printing the Haskell 98 Report.

We'll have to think about how to accumulate further bugs/suggestions for
H98.

Meanwhile, I suspect there's an opportunity for someone (or a small
group) to suggest a new Time library that really does the business, and
provide an implementation.  If it's sufficiently persuasive, all the
implementations will adopt it and it can become a de-facto standard.
The implementation is important because Time is a weird enough thing
that only an expert can implement the spec!  

I think the current Time library suffered because no one who Really
Cared about time was involved in its design or implementation.

Simon
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



RE: time since the epoch

2003-02-03 Thread George Russell
Simon PJ wrote (snipped)
 Meanwhile, I suspect there's an opportunity for someone (or a small
 group) to suggest a new Time library that really does the business, and
 provide an implementation.  If it's sufficiently persuasive, all the
 implementations will adopt it and it can become a de-facto standard.
I already have written a TimeExts library which is in fact bundled with GHC,
namely in -package lang.  What I ought to do, I
suppose, is fishify the comments so Haddock can produce something useful.

Basically it allows you to add a time difference to a ClockTime value to
get another ClockTime value, or subtract two ClockTime values to get a time
difference.  The time difference can be a number of picoseconds, seconds,
minutes, hours, days, months or years.

For all but seconds and picoseconds, it does this by converting to CalendarTime
(using toUTCTime), doing complicated Gregorian calendar calculations (I am
not proud of the code here), and then converting back using toClockTime.
This is probably not a very good way of doing it but at least no-one has
complained about it so far.  Which means either it's perfect or no-one uses
it, I fear the latter.

At least it might be a good idea to start with something like this code,
rather than reinventing the wheel.

Things you need to watch out for are (a) leap seconds; (b) time zones.
I didn't really address the time zone problem, instead doing everything in
UTC.  For us Europeans, it doesn't normally make any difference whether
you use local or UTC time when you ask for the date one month from now.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: time since the epoch

2003-01-31 Thread John Meacham
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
 [EMAIL PROTECTED]
 http://www.haskell.org/mailman/listinfo/haskell
 

-- 
---
John Meacham - California Institute of Technology, Alum. - [EMAIL PROTECTED]
---
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell