-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Add std::time::Duration::{from_days, from_hours, from_mins} #47097
Add std::time::Duration::{from_days, from_hours, from_mins} #47097
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @BurntSushi (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in principle this seems fine, but we should check what other time libraries do. Go, for example, has minutes and hours, but not days. Are there other issues aside from leap seconds with using day
as a duration unit? (I'm pretty sure there is, but I'm not knowledgeable enough to articulate what's inside my head. Days aren't always exactly 24 hours, for example?)
If we do want to keep the from_days
constructor, then we probably want a stronger specification that says that it doesn't do anything special and interprets a day as 24 hours.
cc @rust-lang/libs
src/libstd/time/duration.rs
Outdated
/// assert_eq!(86_400, duration.as_secs()); | ||
/// assert_eq!(0, duration.subsec_nanos()); | ||
/// ``` | ||
#[unstable(feature = "duration_from_hours", issue = "47097")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we generally create a separate (non-PR) tracking issue for new features. I think you can leave it like this for now, but if we do merge this, then I think we'll want to create a tracking issue and then update the PR.
Is that right @alexcrichton?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I note that this feature name is duration_from_hours
, which is the same as the from_hours
method but different from the name duration_from_mins
used for the from_mins
method.
I suspect you probably just want to use one feature name for all of them (duration_from
perhaps?).
src/libstd/time/duration.rs
Outdated
/// ``` | ||
#[unstable(feature = "duration_from_mins", issue = "47097")] | ||
#[inline] | ||
pub fn from_mins(mins: u64) -> Duration { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd rather this be called from_minutes
.
Well there is also the issue of daylight savings time. 5:00 on some day plus Basically, splitting the timestamp into parts, adding one to the day part, and joining it back together can give a different result than adding |
Thanks for the prompt review! Concerning the length of days, they are always strictly 86_400 seconds long, which is strictly 24 hours. (Note that there's also a "sideral day" which lasts 23 hours 56 minutes 4 seconds and a bit, but that notion is only used in some astronomical observations and relies on a different definition of the day.) The confusing part with leap seconds is that there are several "TAI seconds" associated to a unique UTC time. In other words, UTC moves slightly faster than the real atomic time. The issue pinpointed by retep998 #47097 (comment) is valid (and it's the reason Go didn't include Days, cf. golang/go#11473 (comment)), but I would argue that it's an implementor's problem. All that said, if there's a strong preference to not include |
I guess I would personally want to be conservative here and not have a But, I do not have a lot of domain knowledge here so my opinion is held pretty weakly. Let's see what the rest of the library team thinks. :) |
The initial RFC didn’t add these constructors specifically because these units only make sense with a starting date in mind. EDIT:
|
I don't find the argumentation in the initial RFC to be that convincing, if I'm honest. The Joda Time library specifically provides these I'll go ahead and remove the |
Triage ping @rust-lang/libs! (Note that this PR now only provides |
cc @wycats |
Sorry for the delay on this -- @wycats (who has thought deeply about these issues) plans to reply this weekend. |
As noted, the original RFC left out a lot of expected APIs for a few reasons:
An example of (2) is the way that people often use time and duration APIs to benchmark. In many languages, it's common to create the equivalent of There are some problems with this:
Because of the fact that certain times (like the time that comes from In contrast, the RFC I wrote creates a very nice API for tracking elapsed time: let i = Instant::now();
// later
let amount = i.elapsed(); The My philosophy for extensions to the After that very long aside, in this case, I'd like to start by understanding why people want these very large constants to begin with. I can see why somebody would genuinely want a Duration in the seconds (or perhaps even minutes) to conveniently construct parameters to pass to timeouts. But I'm not quite sure why somebody would want hours or days. When looking at my own backend code, I see cases where people are using these very large constants as an approximation for day-based math, which I have strong objections to (day-based math has even more gotchas). So I'd like us to try to enumerate some good examples of code that constructs durations lasting days (or even hours) so we can see what gotchas might apply to them. |
The only good examples I have for measuring hours or days are simulation software. Specifically, a large part of my day-to-day coding involves writing integration software of dynamic systems, and these have time spans on the order of months or years. Even more specifically, I wrote a simulation toolkit last year which, for many reasons, I'll be converting to Rust while adding numerous functionalities. This requires long term precise time measurements (and justifies the coding of hifitime). You may find specific time scale examples in this test file in Go. You'll notice that the integration time steps for the tests run between 24 hours to 190 days. |
@ChristopherRabotin Thanks so much for that information. I've done a review of a lot of my own codebases in various languages, and I don't have any reservations about standardizing seconds. In my own codebases, one antipattern I found with very long durations is that code sometimes relied upon the process itself remaining up, and would have been more resilient by using crons or other externalized timers. Because Instants aren't shareable across processes easily (because monotonic time backends might rely on time-since-process-start), it's not even particularly easy using Writing this comment, I realize we probably should do something about that use case (the ability to store Instant::now() + durably). In my own code, some of the uses of minutes had this problem (better off as crons), but I don't mind adding minutes (as Once you get beyond seconds and minutes, in addition to the problem of reliance on long-lived processes, there is also the problem of edge cases interacting poorly with calendars (adding 1 standard day to midnight might not increment the day when another calendar is in play), and I'd want to see a broader set of use-cases to help drive a possible design for this feature. |
I agree that calendar and specifically time zones are not easy to handle. That's why in Anyhow, would you encourage me to change my PR such that |
☔ The latest upstream changes (presumably #46666) made this pull request unmergeable. Please resolve the merge conflicts. |
@ChristopherRabotin Sorry for the delayed response! My take from @wycats's comment is that he feels comfortable adding minutes, but still feels like hours are ripe for misuse (and are relatively niche). So I think at this point we'd be happy to take |
@aturon , @wycats , if this PR will only add minutes, I really don't see much of a point in all honesty, especially if I need to rewrite this PR to accommodate for the upstream changes. =/ Converting from seconds to minutes doesn't change a whole lot (factor of 60), but I definitely have use in the seconds to hours conversion. Now, if I'm the only one who will ever use this, then I can just continue using the hack I currently use. |
Soo... where do we stand on this PR? Should it just be closed due to disinterest? |
Is the consensus that there should only be a standard minutes initializer?
If so then yes, we should close this PR.
…On Fri, Mar 2, 2018, 17:15 Jake Goulding ***@***.***> wrote:
Soo... where do we stand on this PR? Should it just be closed due to
disinterest?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#47097 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AEma6O037K8RGcxbbZNT7A5812u_lMl9ks5taeCGgaJpZM4RP80O>
.
|
Yep, the consensus seems to have only a minutes initializer. Closing as the author's wish. |
I would love to hear your opinions on minute, hour and day constants discussed in #52556. Proposed solution is to name them as |
Minutes, hours and days* have a fixed number of seconds. Allowing to construct a
Duration
from a number of these common time spans alleviates a minor implementation by each dev needing this.Note of warning: This is my first contribution attempt to the rust code base. I think I've followed all the rules, but let me know if I haven't.
I am already planning to using this in hifitime, and I thought it may be useful to the broader Rust community. BTW,
hifitime
is a crate for date time handling in rust built on top of the current std::time::Duration and it supports leap seconds (which I need for other projects).(*) Days may have an extra second called the leap second. It's announced and determined by the IETF one year around the end of December. In recent years, there's been one leap second every two years. So we can safely assume that when a dev would called
Duration::from_days
they expect the usual number of seconds in a day.Tests passed locally: