doc icon indicating copy to clipboard operation
doc copied to clipboard

confusion about class Instant's epoch

Open arkiuat opened this issue 5 months ago • 7 comments

Problem

In https://docs.raku.org/type/Instant the statement "It is not tied to or aware of any epoch." is an unnecessarily mysterious way of saying that the epoch of Instant is implementation-dependent.

Clearly, every implementation is going to tie Instant to some epoch or another (which the above seems to contradict): it's just that we can't portably rely on what that epoch is going to be.

It would be much less confusing simply to state that the epoch of Instant is not defined by the standard and is implementation dependent. This would have made it clear to me (the above did not!) that the 1969-12-31T23:59:50Z epoch of Rakudo's implementation of Instant was just an implementation choice. [edited to correct thinko]

Suggestions

I would replace the sentence

"It is not tied to or aware of any epoch."

with

"The particular epoch used by Instant is an implementation choice and subject to change at any time."

or if that's too long

"Its epoch is implementation-dependent."

arkiuat avatar Jul 10 '25 21:07 arkiuat

I have a different suggestion. But before I give it I feel I need to motivate it.

the 1969-12-31T12:59:50Z epoch of Rakudo's implementation of Instant was just an implementation choice.

I don't see it that way.

Let me excerpt what I think is about the right amount from the Wikipedia page on Leap seconds, with key parts in italic and critical parts in bold:

In 1972, the leap-second system was introduced so that the UTC second could be set exactly equal to the standard SI second, while still maintaining the UTC time of day and changes of UTC date synchronized with those of UT1.

By then, the UTC clock was already 10 seconds behind TAI, which had been synchronized with UT1 in 1958, but had been counting true SI seconds since then.

After 1972, both clocks have been ticking in SI seconds, so the difference between their displays at any time is 10 seconds plus the total number of leap seconds that have been applied to UTC as of that time; as of 2024, 27 leap seconds have been applied to UTC, so the difference [in 2024] is 10 + 27 = 37 seconds.

As I understand things, the DateTime class must do something sensible about the default default epoch aspect of a DateTime. (Note that that's two uses of "default".)

Furthermore, as I understand things, an epoch with a -10 second offset from midnight January 1st 1970 is the only sane default default epoch for an ISO 8601 compliant date/time stamp.


(That said, I can imagine that a distribution of a Raku compiler (eg Rakudo) and/or the DateTime package could at least conceivably (to me right now), and even somewhat reasonably (as I understand things right now) want to set some other default.)


Also, today is not a date in 1970 or 1971. For most software, someone or something needs to take into account the leap seconds since then. And because we can't usefully precalculate future values (because a committee decides what they are, and when they will be applied), then the DateTime class per se can't sensibly be that something.

So, as I understand things, the doc must make it clear (which it clearly currently doesn't given that you've opened this issue) that something needs to take leap seconds (and perhaps the epoch) into account if users of the DateTime class are to avoid having their Instants off by nearly a half a minute and counting.


I would replace the sentence "It is not tied to or aware of any epoch." with "The particular epoch used by Instant is an implementation choice and subject to change at any time." or if that's too long "Its epoch is implementation-dependent."

I wish I could say what my other suggestion is. But I'll stop here. I just wanted to first motivate an alternate suggestion. And now I'm here I know I need to sleep on it!

Hopefully you understand what I was driving at above.

If so, hopefully you have a suggestion!

raiph avatar Jul 10 '25 23:07 raiph

That all sounds good to me! But takes it beyond being just a documentation issue, I think. librasteve asked on irc why Instant's epoch was implementation-dependent, and I really couldn't come up with any reason other than that people seem pretty vague about which epoch to count seconds from in TAI in general (it used to be 1958-01-01T00:00:00Z, but that was before they corrected for gravitational relativity and synched up TAI with what used to be called Ephemeris Time, and people don't seem to refer to it much).

The point I did make in the conversation was that, IF the epoch of Instant can't be depended on, we DO need to be able to depend on the offset between time and now being 10 s before the first leap second (in 1972), 11 s after it, 37 s now, 36 s before the most recent leap second (in 2016) etc. And not just for the present, but for any arbitrary non-future time. Right now I, and probably a lot of other Raku programmers, rely on the relationship between Instant's epoch-based values in the current implementation with the well-known values of Unix-time to extract this information when needed. There needs to be some reliable method for obtaining the offset in seconds between UT and TAI at any particular point in time.

arkiuat avatar Jul 10 '25 23:07 arkiuat

I agree this goes way beyond a documentation issue.

Please see the Problem Solving discussion https://github.com/Raku/problem-solving/issues/484 which seems a much better place to sort this out.

My comment there strongly recommends a formal implementation in terms of a self-describing structure with year/month/etc components rather than in terms of an integer since an epoch, as being the most future proof and safe from corruption. See there for more details.

duncand avatar Jul 11 '25 00:07 duncand

So the can of worms that has been opened is the question whether the epoch used by Instant in Rakudo is an implementation detail or not.

If it is, then the sentence I was criticizing is merely less than perfectly clear, but if it is not merely an implementation detail, and rather is or should become part of the language definition, then that sentence is positively misleading.

To quote selectively from @raiph 's comment https://github.com/Raku/doc/issues/4608#issuecomment-3059492555

the 1969-12-31T12:59:50Z epoch of Rakudo's implementation of Instant

...

Let me excerpt what I think is about the right amount from the Wikipedia page on Leap seconds, with key parts in italic and critical parts in bold:

In 1972, the leap-second system was introduced so that the UTC second could be set exactly equal to the standard SI second, while still maintaining the UTC time of day and changes of UTC date synchronized with those of UT1.

By then, the UTC clock was already 10 seconds behind TAI, which had been synchronized with UT1 in 1958, but had been counting true SI seconds since then.

After 1972, both clocks have been ticking in SI seconds, so the difference between their displays at any time is 10 seconds plus the total number of leap seconds that have been applied to UTC as of that time; as of 2024, 27 leap seconds have been applied to UTC, so the difference [in 2024] is 10 + 27 = 37 seconds.

As I understand things, the DateTime class must do something sensible about the default default epoch aspect of a DateTime. (Note that that's two uses of "default".)

Furthermore, as I understand things, an epoch with a -10 second offset from midnight January 1st 1970 is the only sane default default epoch for an ISO 8601 compliant date/time stamp.

...

So, as I understand things, the doc must make it clear (which it clearly currently doesn't given that you've opened this issue) that something needs to take leap seconds (and perhaps the epoch) into account if users of the DateTime class are to avoid having their Instants off by nearly a half a minute and counting.

arkiuat avatar Aug 04 '25 03:08 arkiuat

I made a bad conceptual typo on this thread that no one has corrected yet, so I had better correct it before it confuses someone.

The prospective default-default epoch under discussion here is 1969-12-31T23:59:50Z (there is no 12:59 about it!)

% raku -e'with Instant.from-posix(-10) { .say; DateTime.new($_).say }' Instant:0 1969-12-31T23:59:50Z %

arkiuat avatar Sep 17 '25 18:09 arkiuat

I'm wondering whether the larger issue that @raiph raised on 2025 July 10 should be an issue in Raku/problem-solving/. I didn't open one earlier because of @librasteve 's https://github.com/Raku/problem-solving/issues/484 , but that one has since been closed because it included several other issues.

I'd still leave this docs issue open because the wording

It is not tied to or aware of any epoch.

in https://docs.raku.org/type/Instant is still confusing and should be rephrased.

The problem-solving issue would be to decide what it is exactly that we want to state clearly instead of that.

arkiuat avatar Sep 18 '25 13:09 arkiuat

It looks as if problem-solving issue 497 is getting resolved with a definite "yes", and also a long process of deprecation and removal of several methods that never should have been defined for Instant and Duration.

I'll try to come up with some other way to address the confusing wording that I was originally complaining about.

arkiuat avatar Dec 03 '25 13:12 arkiuat