haskell / time

A time library
http://hackage.haskell.org/package/time
Other
119 stars 79 forks source link

Offsets in seconds (Local Mean Time) #174

Closed ysangkok closed 3 years ago

ysangkok commented 3 years ago

I noticed that the tzdb contains Local Mean Time with offsets in seconds. This is returned by popular applications such as PostgreSQL:

janus=> set timezone to 'America/Chicago';
SET
janus=> select '1883-11-18' :: timestamptz;
         timestamptz          
------------------------------
 1883-11-18 00:00:00-05:50:36

It seems like currently, this precision is lost, even when working with time-ng: truncation in timezone-olson which uses timezone-series which uses time.

I am wondering whether it wouldn't be better to offer the second-precision if time-ng is supposed to be a fresh start? It would have to be a separate data type to keep compatibility, but I am making the issue here since the time-ng efforts still seem to base on this time library.

Thank you for your patience and work.

AshleyYakeley commented 3 years ago

Could you clarify what you're looking for? Local Mean Time is based on longitude, is it not?

ysangkok commented 3 years ago

I am looking for a TimeZone type that is specified in seconds, not minutes. I am not sure if there is even a single definition of Local Mean Time. I mention it because that is how I saw the second-granularity offsets. And they do exist, they are part of tzdb.

AshleyYakeley commented 3 years ago

TimeZone indicates offsets from UTC. If you're interested in LMT, you probably want offsets from UT1 instead. If you have a particular longitude, you might consider these functions in Data.Time.LocalTime:

ut1ToLocalTime :: Rational -> UniversalTime -> LocalTime
localTimeToUT1 :: Rational -> LocalTime -> UniversalTime
ysangkok commented 3 years ago

If UTC is not supposed to be used with LMT, and timezone-series by @ygale constructs TimeZone objects for those LMT timestamps (as linked above), then there is a bug in timezone-series. I created the bug here because I thought a more accurate offset type should also live in this library. Is that out of scope for this library? If it is, does that mean that timezone-series should have its own granular offset type?

I raised the fact that the timestamp format (in my initial post here) isn't documented in PostgreSQL, and Tom Lane suggested a patch which mentions "UTC offset specified to seconds (not allowed in ISO 8601)" as the name of this timestamp format. Since that patch doesn't mention UT1, I guess they really are UTC offsets? In that thread on the pgsql-docs list, he also links a suggestion to drop LMT, which apparently went nowhere. Would it make most sense for the current timezone-series API to simply fail if the timestamp would be using LMT? It doesn't seem like there is an API to actually detect that, as Tom notes in the suggestion. So that's another argument for having the same type cover all cases.

AshleyYakeley commented 3 years ago

OK, if we could just focus on the time library...

The time library makes these assumptions:

  1. A time zone offset is relative to UTC
  2. All time zone offsets are whole numbers of minutes.

It seems what TZ is doing is extending UTC back to 1883 as Greenwich Time, and then calculating a time "zone" for Chicago based on the LMT there. And they round that to the second rather than to the minute. Is that correct?

ysangkok commented 3 years ago

And they round that to the second rather than to the minute. Is that correct?

Yes, I believe so. Because if I unpack tzdb-2021a.tar.lz from IANA and look in northamerica, I find these lines:

# Zone  NAME        STDOFF  RULES   FORMAT  [UNTIL]
Zone America/Chicago    -5:50:36 -  LMT 1883 Nov 18 12:09:24
AshleyYakeley commented 3 years ago

Somewhat awkward, but probably doesn't justify a change to the time library?

ysangkok commented 3 years ago

All right. I will close this then. Thank you for the discussion.

yitz-zoomin commented 3 years ago

@AshleyYakeley The timezone-series library is intended to produce timezone offsets that are usable with the time library. Should we make LMT - or perhaps any offset that is not a whole number of minutes - a special case and ignore it? Or round it?

AshleyYakeley commented 3 years ago

I guess round it?

TimeZone is kind of an awkward type.