-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SystemTime does not discuss leap seconds in docs #77994
Comments
To document, we need to know what the actual behavior is. Does anyone know what happens if the clock goes back in time and we try to return the number of milliseconds? |
Coming here after looking for this from chronotope/chrono#21 ; I just want to say that the question, rather than "what is the current behavior", should probably be "what should the behavior be" IMO. The current docs explicitly state that Does what I'm saying make sense? If so I may be willing to try to check it out and work on fixes for platforms that (I can access and) can be fixed properly, and workarounds for platforms that cannot; though I can't promise a timeline. BTW, I'm particularly interested in (Also, leap seconds don't go in the past, though NTP adjustment can definitely make the clock go in the past) |
The behaviour should be that Leap seconds are extremely inconvenient to work with. They are inherently unpredictable, difficult to get reliable information about (existence of some tables and crates notwithstanding). They are also in the process of being abolished, perhaps even before the next one occurs. OTOH the "system time with smeared leap seconds" approach nowadays taken by most common operating systems when synced to network time, works really well. For applications where precise real-time timing is required, |
It is not what is currently documented as the behavior of SystemTime, as While I see your point (and don't really care what the end-choice is, as converting between the two is not too hard), I do think changing the documentation this significantly would also require an RFC, because the current documentation of Basically there are two things that make sense to have. The current documentation claims one, the current implementation… probably is the other? And we need to reconcile the two. |
They are not being abolished, the occurrence of new leap seconds is going to be put off. There will still be a ~30-45s offset between UTC and TAI between 2035 and 2135; and But yes, I'm totally with you that even if the application crashes with leap seconds every time it happens, it's probably not too big a deal anyway, except at the google scale where they had to introduce UTC-SLS because it was too much for them; and I personally don't care that much about google scale. (Edit: Re-reading this, it sounds bad. I'm entirely first-degree here, I really don't care about whether there are leap seconds or not in SystemTime::now, and an offset of 30 seconds won't change my life. I really just care that the documentation and behavior match properly, because otherwise google-scale would be unable to work around whatever issues are raised by the behavior because they wouldn't know about it. They did UTC-SLS once, they can handle it again.) The only thing I really care about is that the documentation and behavior of |
There are a number of crates that assume Outside POSIX APIs, there are protocols that use POSIX seconds since the epoch, e.g. JWT, CBOR, TOTP, certificate transparency, TSIG, DNSSEC, etc usw, and NTP timestamps are the same as POSIX time with a 70 year (2,208,988,800 second) offset. So POSIX-style seconds counts (ignoring leap seconds) are the norm, much more common than seconds counts that include leap seconds. Most unix-like operating systems do not even have a clock that counts time including leap seconds. (You can't use And POSIX time is much more robust: it's just a formula from a broken-down time (in some flavour of UT, officially UTC) to an integer. This means it can trivially represent times in UT before the start of UTC, or in the 1960s rubber seconds period of UTC, or more than 11 months in the future, all of which are outside the range of a leap second table. Even within the range of a leap second table, POSIX time does not depend on dynamic data that is hard to obtain and keep up-to-date in a reliable and portable manner. |
Disclaimer before my message: Again, I agree that posix seconds since epoch is definitely the current de-facto standard in computers, though I disagree that posix is more robust in any way as literally any computer clock is counting TAI and not UTC unless there is software actively messing with leap seconds. Portability that said is definitely a matter, that makes TAI-based timekeeping hard, especially at the standard library level. However, "POSIX seconds since the epoch" is not actually something that has a meaning. POSIX time has a meaning, and matches one point in real-life time with one integer that is not a number of seconds since the epoch. (Nor is it actually UTC, if I can trust djb's claims) If the thing were returning a Unfortunately, this is not something that can happen today. Honestly, the thing I would personally be most happy with would be deprecating |
The current behavior is that SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() matches libc::time() . I think that it should continue being so. |
Document that SystemTime does not count leap seconds Fixes rust-lang#77994 This may not be entirely uncontroversial. I know that `@Ekleog` is going to disagree. However, in support of this docs change: This documents the current behaviour. The alternative would be to plan to *change* the behaviour. There are many programs which need to get a POSIX time (a `time_t`). Right now, `duration_since(UNIX_EPOCH)` is the only facility in std that does that. So, that is what programs use. Changing the behaviour would break[1] all of those programs. We would need to define a new API that can be used to get a POSIX time, and get everyone to use it. This seems highly unpalatable. And, even if we wanted to do that, time with leap seconds is a lot less easy to work with. We would need to arrange to have a leap seconds table available to `std` somehow, and make sure that it was kept up to date. Currently we don't offer to do that for timezone data, which has similar needs. There are other complications. So it seems it would be awkwarrd to *implement* a facility that provides time including leap seconds, and the resulting value would be hard for applications to work with. Therefore, I think it's clear that we don't want to plan to ever change `SystemTime`. We should plan to keep it the way it is. Providing TAI (for example) should be left to external crates, or additional APIs we may add in the future. For more discussion see rust-lang#77994 and in particular `@fanf2's` rust-lang#77994 (comment) [1] Of course, by "break" we really only mean *future* breakage in the case where there is, in fact, ever another leap second. There may well not be: they are in the process of being abolished (although this is of course being contested). But if we decide that `SystemTime::now().duraton_since(UNIX_EPOCH)` counts leap seconds, it would start to return `Durations`s that are 27s different to the current answers. That's clearly unacceptable. And we can hardly change `UNIX_EPOCH` by 27s.
Document that SystemTime does not count leap seconds Fixes #77994 This may not be entirely uncontroversial. I know that `@Ekleog` is going to disagree. However, in support of this docs change: This documents the current behaviour. The alternative would be to plan to *change* the behaviour. There are many programs which need to get a POSIX time (a `time_t`). Right now, `duration_since(UNIX_EPOCH)` is the only facility in std that does that. So, that is what programs use. Changing the behaviour would break[1] all of those programs. We would need to define a new API that can be used to get a POSIX time, and get everyone to use it. This seems highly unpalatable. And, even if we wanted to do that, time with leap seconds is a lot less easy to work with. We would need to arrange to have a leap seconds table available to `std` somehow, and make sure that it was kept up to date. Currently we don't offer to do that for timezone data, which has similar needs. There are other complications. So it seems it would be awkwarrd to *implement* a facility that provides time including leap seconds, and the resulting value would be hard for applications to work with. Therefore, I think it's clear that we don't want to plan to ever change `SystemTime`. We should plan to keep it the way it is. Providing TAI (for example) should be left to external crates, or additional APIs we may add in the future. For more discussion see #77994 and in particular `@fanf2's` rust-lang/rust#77994 (comment) [1] Of course, by "break" we really only mean *future* breakage in the case where there is, in fact, ever another leap second. There may well not be: they are in the process of being abolished (although this is of course being contested). But if we decide that `SystemTime::now().duraton_since(UNIX_EPOCH)` counts leap seconds, it would start to return `Durations`s that are 27s different to the current answers. That's clearly unacceptable. And we can hardly change `UNIX_EPOCH` by 27s.
SystemTime
ought to explain what happens with leap seconds.In particular, the current text under
SystemTime::UNIX_EPOCH
suggests using.duration_since()
to get "Using duration_since on an existing SystemTime instance can tell how far away from this point in time a measurement lies".A programmer who is reading this and does not know of the existence of leap seconds will assume that the result is a Unix
time_t
(with additional precision). I think this is in fact the case, but this is not stated and it should be.I am filing this as a bug report because the lack of an explicit statement in the documentation makes it impossible to confidently write code which receives or emits unix times, even though that does seem to be the point of the
UNIX_EPOCH
constant.It would probably be useful to mention leap seconds as a reason why the clock might go backwards or might not run at a constant rate, along with clock adjustments (the implications of which are discussed without naming them!)
The text was updated successfully, but these errors were encountered: