Skip to content
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

Document that SystemTime does not count leap seconds #109660

Merged
merged 3 commits into from
Aug 28, 2023
Merged

Conversation

ijackson
Copy link
Contributor

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 #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 Durationss that are 27s different to the current answers. That's clearly unacceptable. And we can hardly change UNIX_EPOCH by 27s.

I edited one of these and looked at the formatted docs for the other.
This confused me for a while; I suspected a build system bug.

I don't see an easy and neat way to unify these.  So let's just
document it instead.
@rustbot
Copy link
Collaborator

rustbot commented Mar 27, 2023

r? @thomcc

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Mar 27, 2023
@rustbot
Copy link
Collaborator

rustbot commented Mar 27, 2023

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with @rustbot label +T-libs-api -T-libs to tag it appropriately. If this PR contains changes to any unstable APIs please edit the PR description to add a link to the relevant API Change Proposal or create one if you haven't already. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

@ijackson
Copy link
Contributor Author

@rustbot label +T-libs-api -T-libs

@rustbot rustbot added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Mar 27, 2023
@Ekleog
Copy link

Ekleog commented Mar 29, 2023

My opposition is more of a principled opposition: I think we should eventually deprecate duration_since in favor of some other name that makes it clear that the returned number is not an actual duration.

However, I'm still all an favor of fixing the documentation so that at least the current behavior is well-documented :)

I'm just thinking this PR is missing the place that is actually most subject to issues, which is the duration_since method; as the following code might have very surprising behavior if presented with a leap second even on an otherwise well-behaved system… and it's actually the code example that's currently being given to SystemTime::duration_since: (including, I'd guess, probably panicking on some OSes, though hopefully none of the main ones)

let start = SystemTime::now();
do_stuff();
println!("Time it took to run do_stuff: {:?}", SystemTime::now().duration_since(start).unwrap())

@thomcc
Copy link
Member

thomcc commented Mar 30, 2023

Our behavior here is clearly an API decision, that requires some amount of discussion, so I'm nominating this.

The status quo is that we do not count leap seconds. Do we want to guarantee that, or leave it open to change? There is further discussion in #77994.

@thomcc thomcc added the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Mar 30, 2023
@m-ou-se
Copy link
Member

m-ou-se commented Apr 25, 2023

We discussed this in a recent libs api meeting. We came to the same conclusion as above: the only way to convert a SystemTime to a date/time currently is by subtracting UNIX_EPOCH from it. If the resulting Duration would include leap seconds, an accurate conversion wouldn't be possible. (Even if we were to ship a database of leap seconds; future leap seconds aren't even known yet.)

So, SystemTime should not include leap seconds, and we should document that guarantee. Any other option would make SystemTime mostly unusable and incompatible with how it's already used in many places today.

@m-ou-se m-ou-se removed the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Apr 25, 2023
@ijackson
Copy link
Contributor Author

So, SystemTime should not include leap seconds, and we should document that guarantee. Any other option would make SystemTime mostly unusable and incompatible with how it's already used in many places today.

Cool, thanks. That's what I'm intending with the text in this MR. @thomcc, does that text look good to you?

@jyn514 jyn514 added the A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools label Apr 26, 2023
Copy link
Member

@thomcc thomcc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay, I had some family issues that caused me to fall behind on reviews.

A bit bikesheddy, but I would prefer these have their wording tweaked.

/// returns a POSIX `time_t` (as a `u64`):
/// the number of non-leap seconds since the start of 1970 UTC.
/// This is the same time representation as used in many Internet protocols,
/// for example: JWT, CBOR, TOTP, certificate transparency and DNS TSIG/DNSSEC.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think enumerating these probably is over the line for too much documentation, since it might lead people to file PRs adding other protocols. I also would prefer saying "This is $description, same as $POSIX_equivalent" rather than the other way around.

So my suggesion would be for this (and the other) comment to be more like:

duration_since(UNIX_EPOCH).unwrap().as_secs() returns the number of non-leap seconds since the start of 1970 UTC, as a u64. This is the same time representation as used in POSIX time_t, as well as a wide variety of internet protocols.

(Note: I'm not tied to precise wording except for the bits I mentioned above). Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm OK with these suggestions and have adopted them. Thanks.

@thomcc
Copy link
Member

thomcc commented May 5, 2023

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 5, 2023
 * Make the description primary, not the definition in terms of time_t
 * Remove the list of Internet protocols

As per
  rust-lang#109660 (review)
@ijackson
Copy link
Contributor Author

ijackson commented Aug 7, 2023

@rustbot reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 7, 2023
@thomcc
Copy link
Member

thomcc commented Aug 28, 2023

@bors r+

@bors
Copy link
Contributor

bors commented Aug 28, 2023

📌 Commit c4bc16c has been approved by thomcc

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 28, 2023
@thomcc
Copy link
Member

thomcc commented Aug 28, 2023

@bors rollup

bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 28, 2023
…iaskrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang#109660 (Document that SystemTime does not count leap seconds)
 - rust-lang#114238 (Fix implementation of `Duration::checked_div`)
 - rust-lang#114512 (std/tests: disable ancillary tests on freebsd since the feature itsel…)
 - rust-lang#114919 (style-guide: Add guidance for defining formatting for specific macros)
 - rust-lang#115278 (tell people what to do when removing an error code)
 - rust-lang#115280 (avoid triple-backtrace due to panic-during-cleanup)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit fb98f7a into rust-lang:master Aug 28, 2023
11 checks passed
@rustbot rustbot added this to the 1.74.0 milestone Aug 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SystemTime does not discuss leap seconds in docs
7 participants