Skip to content

Tracking Issue for duration_constructors #120301

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

Open
1 of 3 tasks
djc opened this issue Jan 24, 2024 · 46 comments
Open
1 of 3 tasks

Tracking Issue for duration_constructors #120301

djc opened this issue Jan 24, 2024 · 46 comments
Labels
C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@djc
Copy link
Contributor

djc commented Jan 24, 2024

Feature gate: #![feature(duration_constructors)]

This is a tracking issue for supporting larger unit sizes for Duration constructors.

Public API

Add the following constructors to Duration:

  • Duration::from_weeks()
  • Duration::from_days()
  • Duration::from_hours()
  • Duration::from_mins()

Steps / History

@djc djc added C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Jan 24, 2024
@the8472
Copy link
Member

the8472 commented Jan 24, 2024

Similar things were previously proposed in #47097, #52556
They were intentionally omitted in RFC 1040 because leap seconds complicate things to make time-calculations non-trivial.

Imo it requires some significant discussion to add these. A PR and a tracking issue without context are insufficient.

@djc
Copy link
Contributor Author

djc commented Jan 24, 2024

Thanks for adding this context. I was fairly certain that this would have been discussed before, but searching the issue tracker (for open issues) didn't turn up any existing discussion. I think it's okay to have this discussion here/now?

From RFC 1040:

This proposal does not, at this time, include mechanisms for instantiating a Duration from weeks, days, hours or minutes, because there are caveats to each of those units. In particular, the existence of leap seconds means that it is only possible to properly understand them relative to a particular starting point.

It goes on to quote JodaTime documentation; I'll quote the current version of this:

A period in Joda-Time represents a period of time defined in terms of fields, for example, 3 years 5 months 2 days and 7 hours. This differs from a duration in that it is inexact in terms of milliseconds. A period can only be resolved to an exact number of milliseconds by specifying the instant (including chronology and time zone) it is relative to.

Note that the RFC is from 2015 and the latest discussion in #52556 is from 2018 so I feel like revisiting this decision isn't all that crazy.

Personally I feel this distinction is well-established in the Rust ecosystem at this point, and there's a clear interplay between SystemTime (grounded in real-world time) and Duration (which presents a pure duration). As such, I personally don't feel like leap seconds are a good reason to avoid adding these. I would also argue that both chrono and time are very popular libraries in the ecosystem, and both have made these available seemingly without many ill effects.

IMO each of these constructors have a clear unambiguous meaning in the context of a Duration. If we want, we could of course add some documentation that leap seconds are not considered.

Note: I happen to be the current chrono maintainer, so I have some background in these things.

@Mark-Simulacrum
Copy link
Member

We may want to consider as part of stabilization whether these could "just" (or in addition should be) associated constants. e.g., Duration::WEEK * 5 == Duration::from_weeks(5). We have paired constants for all existing constructor functions: millisecond, second, and nanosecond.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Feb 11, 2024
…Simulacrum

core: add Duration constructors

Add more `Duration` constructors.

Tracking issue: rust-lang#120301.

These match similar convenience constructors available on both `chrono::Duration` and `time::Duration`.

What's the best ordering for these with respect to the existing constructors?
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Feb 11, 2024
Rollup merge of rust-lang#120307 - djc:duration-constructors, r=Mark-Simulacrum

core: add Duration constructors

Add more `Duration` constructors.

Tracking issue: rust-lang#120301.

These match similar convenience constructors available on both `chrono::Duration` and `time::Duration`.

What's the best ordering for these with respect to the existing constructors?
@djc
Copy link
Contributor Author

djc commented Feb 12, 2024

We may want to consider as part of stabilization whether these could "just" (or in addition should be) associated constants. e.g., Duration::WEEK * 5 == Duration::from_weeks(5). We have paired constants for all existing constructor functions: millisecond, second, and nanosecond.

I'm happy to add them, but I'd be disappointed to remove the new constructors in favor of these.

@Victor-N-Suadicani
Copy link
Contributor

Just thought about this and found this issue :)

I prefer the constructors to associated constants.

Have you considered making the constructors take u32 instead of u64, so they don't need to worry about overflow and hence panicking? You lose the option of making a duration longer than u32::MAX * 60 seconds using the from_mins constructor, but that's like 8171 years, so maybe it's okay? 😅

(PS: I think the panic message in from_weeks mistakenly says from_days)

@neumann-paulmann
Copy link

neumann-paulmann commented May 14, 2024

(PS: I think the panic message in from_weeks mistakenly says from_days)

Yup. That looks like a classic case of copy-paste error.

Also

Duration::from_secs(weeks * MINS_PER_HOUR * SECS_PER_MINUTE * HOURS_PER_DAY * DAYS_PER_WEEK)

is rather confusing.
Why not order the constants accordingly to make it simpler to reason about this like of code? E.g.:

Duration::from_secs(SECS_PER_MINUTE * MINS_PER_HOUR * HOURS_PER_DAY * DAYS_PER_WEEK * weeks)

@edwardwc
Copy link

@Mark-Simulacrum @djc I have attempted to add these associated constants in an idiomatic manner: #127700

I would love your feedback!

@eggyal
Copy link
Contributor

eggyal commented Jul 14, 2024

I notice that it isn't currently proposed to add Duration::from_months or Duration::from_years constructors. Why not? Presumably because their durations are variable. Of course, we could document that such constructors are based on a month being exactly 30 days and a year being exactly 365 days, each of exactly 24 hours each of exactly 60 minutes each of exactly 60 seconds... but wouldn't that just be a footgun that users would often misuse and then puzzle over buggy results? Is not the same true of leap seconds and the proposed constructors?

@ChrisDenton
Copy link
Member

We also don't have from_centuries or from_millenia. But these are convenience functions so they're not essential. There's no reason to add them just to round out the API.

It's notable that neither chrono nor time equivalents of Duration are interested in years, which suggests there's no great demand for the API.

@liigo
Copy link
Contributor

liigo commented Dec 26, 2024

In particular, the existence of leap seconds means that it is only possible to properly understand them relative to a particular starting point.

1 minute = 60 seconds. I don't think the leap second should be involved in (if then, 1 second != 1 second, Duration::from_secs shouldn't exist too).

@tbu-
Copy link
Contributor

tbu- commented Jan 16, 2025

Is there motivation for these constructors beyond the following?

These match similar convenience constructors available on both chrono::Duration and time::Duration.

If there's no motivation except for this, I think we should rather omit them from the standard library and let users be explicit that they want to sleep for 300 seconds and not 5 minutes (the latter being ambiguous wrt. leap seconds).

@youknowone
Copy link
Contributor

youknowone commented Jan 17, 2025

Leap second is a concept about absolute time - more specifically, about calendar. Duration is about the amount of time. Even though leap seconds affect the time related API design, it will be related to Instant, SystemTime or something else, not to Duration.

23:59:45 + 60 seconds could be one of 24:00:44, 24:00:45 or 24:00:46 by how to design the absolute time. But the duration 60 seconds could mean a physical quantity 60 seconds. If this still can be ambiguous, this can be documented enough on Duration.

@TimNN
Copy link
Contributor

TimNN commented Apr 16, 2025

Some prior art from other languages / libraries:

  • Abseil Time Durations:
    • Has up to absl::Hours(...)
  • java.time.Duration
    • Has up to Duration::ofDays(...)
    • The first sentence of the doc comment is very precise:
      • "[...] representing a number of standard 24 hour days"
      • "[...] representing a number of standard hours"
      • "[...] representing a number of standard minutes"
      • Smaller units lack the "standard"

Ohter languages and libraries that I checked1 did not have a comparable "Duration" concept. If you know of any, let me know and I'll be happy to add them.

Personal thoughts:

  • "weeks" feel like a property of Civil Time
    • Maybe there are even calendar systems that define them differently?
  • I like how explicit the Java documentation is
    • Especially that it mentions "24 hours" for the "days" factory.

Footnotes

  1. C++'s chrono is heavily template-based, Python's timedelta stores days as a separate component, JavaScript's luxon stores all units as separate components

@BurntSushi
Copy link
Member

BurntSushi commented Apr 16, 2025

I'm fine with adding hours/minutes constructors. I think those are pretty uncontroversial in what their semantics ought to be. Only leap seconds impact the length of an hour/minute, but we should just do what everyone else does and what SystemTime does: ignore leap seconds. Especially just for the constructors. That is, I'm not aware of real world use cases where someone wants to write Duration::from_mins(1) and expect that to be anything other than 60 seconds. AFAIK, not even hifitime makes that distinction, and its main selling point is that it doesn't ignore leap seconds.

But I'm strongly opposed to adding a constructor based on units of days (or anything bigger). I think that's a major mistake because it is common for days to not be 24 hours and for this to actually matter to humans. The new Javascript Temporal API, for example, generally does not let you treat days as "always 24 hours" unless you're explicitly working with civil time. When you're working with zoned datetimes, then 1 day might be more or less than 24 hours.

@Dietr1ch
Copy link

Dietr1ch commented Apr 18, 2025

I'm not aware of real world use cases where someone wants to write Duration::from_mins(1) and expect that to be anything other than 60 seconds. AFAIK, not even hifitime makes that distinction, and its main selling point is that it doesn't ignore leap seconds.

I don't think the ("absolute") time keeping subtleties like leap second smearing, timezone differences or daylight saving time changes would trip people.

A Duration measures length of the passing of time, and time keeping subtleties around "absolute time" have nothing to do with this length.

Maybe English isn't the best language to describe this as "time" is used for both, "absolute time" and relative time, but I think it's better to admit this ambiguity that often appears on spoken language and stick to well defined Duration and Time concepts that many other libraries already use and seem to be well understood already.


I'm not aware of real-world confusion, but only some cautious pushback around "standard" minutes/hours/days/weeks. (Yeah, I guess months being 30 days or years 365 days would be harder to justify, but still somewhat reasonable picks if we ever want to go there).

@BurntSushi
Copy link
Member

I don't think the ("absolute") time keeping subtleties like leap second smearing, timezone differences or daylight saving time changes would trip people.

They can and do. Compare adding 1 day to 2025-03-08T17:00-05 in New York and adding 24 hours.

(Yeah, I guess months being 30 days or years 365 days would be harder to justify, but still somewhat reasonable picks if we ever want to go there).

Those might be reasonable in specific contexts where the error is deemed acceptable, but I think it is a terrible choice to make for a general purpose library.

@Dietr1ch
Copy link

Dietr1ch commented Apr 18, 2025

They can and do. Compare adding 1 day to 2025-03-08T17:00-05 in New York and adding 24 hours.

Doing that where? This to me seems to be an issue with defining the + operator to deal with a Time + Duration sum.

When trying to define the length of Duration::from_days(1) to be the same as Duration::from_hours(24) we haven't even mentioned "absolute time" (Time) yet.

Maybe what we need to avoid possible footguns is to properly define + for Time+Duration and its subtlety-aware evil twin as fundamentally different functions.

@Dietr1ch
Copy link

Dietr1ch commented Apr 18, 2025

Also, like BurntSushi suggested, since the controversial bits seem to be mostly around Duration::from_weeks and Duration::from_days, is it possible to either split this, or partially deliver this to get Duration::from_hours and Duration::from_mins out sooner?

I'm mostly interested on not forcing people to download a new nightly build every day just because of these 2 missing functions.

@BurntSushi
Copy link
Member

BurntSushi commented Apr 18, 2025

Doing that where? This to me seems to be an issue with defining the + operator to deal with a Time + Duration sum.

Huh? Any datetime library is likely going to support adding std::time::Duration to whatever datetime types they provide. By the time you get to + (or whatever the equivalent operation is named, it doesn't matter if it's literally using the + operator), any knowledge about whether the units were specified as "days" or something else is lost. So there is no way to do it differently. The only way to avoid the footgun is to not provide a constructor that automatically assumes days are always 24 hours.

Also, like BurntSushi suggested, since the controversial bits seem to be mostly around Duration::from_weeks and Duration::from_days, is it possible to either split this, or partially deliver this to get Duration::from_hours and Duration::from_mins out sooner?

I would just drop weeks and days, yes. I don't see them ever becoming stable. I would strongly object to them.

I'm mostly interested on not forcing people to download a new nightly build every day just because of these 2 missing functions.

I have no idea what you mean by this.

@the8472
Copy link
Member

the8472 commented Apr 18, 2025

TAI has no leap seconds or time zones (and thus no DST). We could call it from_tai_days

@BurntSushi
Copy link
Member

I don't think that's any less of a footgun.

@Dietr1ch
Copy link

My 5-minute tea won't be ready any sooner when there's leap seconds, daylight saving time changes or leap years. Instructions to make it say to wait 5 minutes and that always means 5*60 seconds no matter the when I start or how fast I move at, just like a dozen means 12 regardless of potential taxes.

The gap for confusion comes from bringing in concepts from absolute time, like day, year and their subdivisions as handy multipliers, and having people not agree on how Time+Duration should work when the Duration was created using the borrowed time multipliers from absolute concepts, but curiously not when it was crafted from seconds (because here them they seem to agree and use the Caesium-133 based definition instead of being a subdivision of a day).

I don't think Duration and its new and old multipliers are confusing. To me the source of confusion arises from missing a CivicTimeDelta struct to use when people care about absolute time and its subtleties more than the actual passage of time.

@BurntSushi
Copy link
Member

BurntSushi commented Apr 18, 2025

Okay, this is going in circles. Unless this moves forward substantively, I'm done after this.

I don't know why you're talking about Caesium-133 or leap seconds. I already told you my concern: DST. This is a real world footgun. Consider this program where we start with an appointment scheduled at 2025-03-08T13:00-05 in New York. And then we want to reschedule it for "one day later." Look at what happens.

Here is the Cargo.toml:

[package]
publish = false
name = "jiff-play"
version = "0.1.0"
edition = "2024"

[dependencies]
anyhow = "1.0.86"
jiff = "0.2"

[[bin]]
name = "jiff-play"
path = "main.rs"

[profile.release]
debug = true

Here is main.rs:

use std::time::{Duration, SystemTime};

use jiff::{tz::TimeZone, Zoned};

fn main() -> anyhow::Result<()> {
    let tz = TimeZone::get("America/New_York")?;

    let appointment = SystemTime::UNIX_EPOCH + Duration::from_secs(1741456800);
    println!(
        "appointment at: {}",
        Zoned::try_from(appointment)?.with_time_zone(tz.clone())
    );

    // same time next tomorrow! so just add 1 day.
    let rescheduled = appointment + from_days(1);

    println!(
        "appointment rescheduled to: {}",
        Zoned::try_from(rescheduled)?.with_time_zone(tz.clone())
    );

    Ok(())
}

fn from_days(days: u64) -> Duration {
    Duration::from_secs(days * 86400)
}

And here is the output:

$ cargo r -q
appointment at: 2025-03-08T13:00:00-05:00[America/New_York]
appointment rescheduled to: 2025-03-09T14:00:00-04:00[America/New_York]

I used Jiff just to print the datetimes so that the mistake is clear, but the mistake occurs with just using standard library APIs in addition to the proposed from_days constructor for std::time::Duration. While you do get a time that is 24 hours later, the time is not what humans think of when you say "1 day later." But by fixing Duration::from_days to 24 hours, you end up with a footgun where it's not actually implementing the concept of day correctly, as humans use it.

This mistake is very easy to hit because you don't even need to be at or near a time zone transition for this to occur. You just need your duration to cover a time zone transition and you'll end up with an unintuitive result.

The bottom line here is that humans tend use the unit of "day" in a way that leads to a variable length definition. It is usually but not always 24 hours. This doesn't apply to minutes. Humans essentially never use the unit "minute" to mean anything other than 60 SI seconds. So when you keep talking about leap seconds and cesium atoms despite the fact that I've already made it clear that it's the interaction of DST (and more generally, any time zone transition) and calendar units that concerns me, it gets very frustrating because it seems like you aren't really engaging with what I'm saying.

Civil time versus absolute time doesn't really have anything to do with the calculus here. This is why I wrote my example above demonstrating the footgun using only standard library APIs. Now, sometimes it is appropriate to assume all days are 24 hours. For example, if you're only doing civil time arithmetic, then that makes sense. Totally cool with that and really nothing can go wrong. But a std::time::Duration is not only for use with civil time. So it doesn't make sense to fix an assumption about the length of days that would only be appropriate in the context of civil time.

@pravic
Copy link
Contributor

pravic commented Apr 18, 2025

But by fixing Duration::from_days to 24 hours, you end up with a footgun where it's not actually implementing the concept of day correctly, as humans use it.

@BurntSushi With all due respect, std::time::Duration is time duration and that's it - it's just a number of seconds, even its documentation says exactly this. It doesn't give any promises or implications about the real world time and everything - it's just duration of the time.

Regardless of from_days being permitted or forbidden, people will always write let day = Duration::from_secs(60 * 60 * 24) and nothing will stop them.

It's where to apply this duration matters - whether to std::time::Instant (which is totally valid) or std::time::SystemTime (which can be wrong) - it's a totally different problem and it should be addressed when someone tries to do the math with the SystemTime, not when someone tries to create a Duration.

As for the DST problem - but all of the Duration constructors are affected by this, whether it be from_days, from_hours, from_mins, or even from_secs. You can even do DST_timestamp - 1 second + 2 seconds and already get the wrong result if the time library you use doesn't know about the DST concept. Can we say that the problem with the 2 seconds here? Of course, not.

@BurntSushi
Copy link
Member

With all due respect, std::time::Duration is time duration and that's it - it's just a number of seconds, even its documentation says exactly this.

I don't really understand why you're telling me this. I mean, I know what a std::time::Duration is. The proposal here is to an establish an equivalence between the concept of a "day" and a precise number of seconds. That equivalence is sometimes okay, but not always, as the example I just showed demonstrated very clearly.

Regardless of from_days being permitted or forbidden, people will always write let day = Duration::from_secs(60 * 60 * 24) and nothing will stop them.

Yup, that's fine. I'm not seeking to prevent all mistakes. I'm looking to prevent some of them, such as the misconception that a day is always 24 hours.

It's where to apply this duration matters - whether to std::time::Instant (which is totally valid) or std::time::SystemTime (which can be wrong) - it's a totally different problem and it should be addressed when someone tries to do the math with the SystemTime, not when someone tries to create a Duration.

I gave an example. Please respond with one. If Duration::from_days exists, how are you going to prevent the footgun I demonstrated?

@BurntSushi
Copy link
Member

BurntSushi commented Apr 18, 2025

You can even do DST_timestamp - 1 second + 2 seconds and already get the wrong result if the time library you use doesn't know about the DST concept. Can we say that the problem with the 2 seconds here? Of course, not.

No, you're mistaken. It really is the concept of day that matters here. Let's modify my program above to try out your claimed footgun:

use std::time::{Duration, SystemTime};

use jiff::{tz::TimeZone, Zoned};

fn main() -> anyhow::Result<()> {
    let tz = TimeZone::get("America/New_York")?;

    // The second before DST starts in New York.
    let t1 = SystemTime::UNIX_EPOCH + Duration::from_secs(1741503599);
    println!("{}", Zoned::try_from(t1)?.with_time_zone(tz.clone()));

    // add 2 seconds
    let t2 = t1 + Duration::from_secs(2);
    println!("{}", Zoned::try_from(t2)?.with_time_zone(tz.clone()));

    // subtract 1 second
    let t3 = t2 - Duration::from_secs(1);
    println!("{}", Zoned::try_from(t3)?.with_time_zone(tz.clone()));

    Ok(())
}

Its output:

$ cargo r -q
2025-03-09T01:59:59-05:00[America/New_York]
2025-03-09T03:00:01-04:00[America/New_York]
2025-03-09T03:00:00-04:00[America/New_York]

Those are all perfectly in keeping with what a human would expect. Formatting it requires the datetime library to be aware of the DST, but the actual arithmetic here is just fine. There's no footgun or mistake.

@the8472
Copy link
Member

the8472 commented Apr 18, 2025

We could turn this around, how is one supposed to express "one day in elapsed actual time" rather than "same time, one day forward on the calendar"? E.g. when trying to compute the amount of GPU-days spent on a renderjob.

@BurntSushi
Copy link
Member

I would question that "one day in elapsed actual time" has an unambiguous meaning. But I have no problem asking users to write Duration::from_hours(24) for cases where they really want "days" to mean "always 24 hours." What I'm objecting to here is a universal claim that days are always 24 hours absent any other context.

@the8472
Copy link
Member

the8472 commented Apr 18, 2025

Then how would you normally provide this context? Should we make duration generic over a clock source? I don't think this is possible retroactively because durations can be transplanted between Instant and SystemTime mentioned above.

@BurntSushi
Copy link
Member

BurntSushi commented Apr 18, 2025

Then how would you normally provide this context?

In std? I don't think I would. Or at least, we'd need to back all the way up and re-examine what problem we're trying to solve. In this context, we're looking to add a few convenience constructors whose utility is presumably self-evident. I'm opposed to convenience constructors for std::time::Duration based on calendar units because it isn't always appropriate and has real world footguns. But if we want to seriously consider alternative designs for appropriately contextualizing the concept of "days," then we've left the neighborhood of self-evidently useful utility constructors. The framing of the discussion would need to totally change.

@pravic
Copy link
Contributor

pravic commented Apr 18, 2025

I gave an example. Please respond with one. If Duration::from_days exists, how are you going to prevent the footgun I demonstrated?

@BurntSushi I am no expert in time libraries, but Chrono seems do the job: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f1cd329588b14f9580cddc59965481a5.

@Dietr1ch
Copy link

I gave an example. Please respond with one. If Duration::from_days exists, how are you going to prevent the footgun I demonstrated?

@BurntSushi I am no expert in time libraries, but Chrono seems do the job: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f1cd329588b14f9580cddc59965481a5.

Note that on the example on 2025-03-09 NY is no longer at UTC-05:00, but at UTC-04:00.

@BurntSushi
Copy link
Member

BurntSushi commented Apr 18, 2025

I gave an example. Please respond with one. If Duration::from_days exists, how are you going to prevent the footgun I demonstrated?

@BurntSushi I am no expert in time libraries, but Chrono seems do the job: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f1cd329588b14f9580cddc59965481a5.

It does not. 2025-03-09 13:00:00 -05:00 isn't valid for New York. By that point, it's in DST and should have an offset of -04.

Case in point, with your setup, Chrono will let you generate a time that will literally never appear on the clocks in New York: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=8c06a26675f11c2f1e17c5f572e3b40b

You need to be using chrono-tz to get the correct behavior here.

(This is one of the many reasons I went out and built Jiff.)

@the8472
Copy link
Member

the8472 commented Apr 18, 2025

I'm opposed to convenience constructors for std::time::Duration based on calendar units because it isn't always appropriate and has real world footguns.

Well, they're also physical units because almost nobody uses megaseconds.
For example NIST recognizes days as a time unit equivalent to 86400s, the IAU even uses the julian year as a fixed unit, e.g. for the lightyear definition.

This is what I was aiming for with from_tai_days, I was trying to provide the context that they're physical units of time, not calendar time.

@tyilo
Copy link
Contributor

tyilo commented Apr 18, 2025

Isn't the problem with days and DST the same for minutes and leap seconds?

@BurntSushi
Copy link
Member

Sure. The problem is that "day" is an overload term. It is difficult to establish the right context while still using the word "day." Like it just doesn't seem worth it to be given how easy the footgun is personally.

@Dietr1ch
Copy link

Dietr1ch commented Apr 18, 2025

It seems to me we just need a CivicTimeOffset struct to signify the offset humans think of when you say "1 day later"

//                                                                                       |  |
let appointment = SystemTime::UNIX_EPOCH + Duration::from_secs(1741456800);  // 2025-03-08T13:00:00-05:00[America/New_York]
let poorly_rescheduled  = appointment + Duration::from_days(1);              // 2025-03-09T14:00:00-04:00[America/New_York]
let civicly_rescheduled = appointment + CivicTimeOffset::days(1);            // 2025-03-09T13:00:00-04:00[America/New_York]

We should probably delay Duration::from_days and larger multipliers until we have something to signify "tomorrow, same time" also coming to the standard library (which might be never due to how hairy absolute time can get).

(had to move this because it got lost amidst a discussion)

@BurntSushi
Copy link
Member

Isn't the problem with days and DST the same for minutes and leap seconds?

Already addressed above: #120301 (comment)

@BurntSushi
Copy link
Member

Adding an entirely different duration type seems like a major escalation to me. It's also a totally different discussion from my perspective, and starts walking down the path of "let's add datetime support to std." Doing it half-assed would be a disaster. If you really want to have that discussion, I'd suggest opening a new issue so that we don't get derailed from considering the much more narrow proposal of convenience constructors on Duration.

@Dietr1ch
Copy link

Adding an entirely different duration type seems like a major escalation to me. It's also a totally different discussion from my perspective, and starts walking down the path of "let's add datetime support to std." Doing it half-assed would be a disaster.

I'm aware of this. The progression we all seem to foresee is,

  1. Adding Duration::from_mins and Duration::from_hours
  2. Properly modeling DateTime and its subtleties in std
  3. Adding Duration::from_days and friends as now we warn people that they might not be doing what they meant and finally give them a working alternative.

And of course 2 is a huge task, but that shouldn't stop everyone from getting 1. soon.

@BurntSushi
Copy link
Member

If from_days and from_weeks are removed, I'd be happy to start an FCP here.

@youknowone
Copy link
Contributor

youknowone commented Apr 18, 2025

I am glad we seem overcoming the leap second issue.

Unfortunately, the definition of day is too much ambiguous. It even doesn't have a single definition in science.

I'd like to remind a thing. Convenience constructors are provided for convenience. They don't provide a new real feature.

If the name matters, I hope the next discussion to be not to have or not the specifically named function from_days, but whether we need the concept of from_days or not. If not, we don't need to worry about the name. Otherwise, we can avoid the name from_days and discuss a better name of it.

@youknowone
Copy link
Contributor

While I have no idea how much from_weeks is useful, I had experience (not the name of but) the concept of from_days is useful to help not to do * 86400 everywhere. Its name may can be from_24hours, which is not very attractive though.

At the same time from_days is still less useful than from_mins or from_hours. I upvote for from_mins and from_hours regardless how others go.

@Dietr1ch
Copy link

So, to play the devil's advocate against from_mins and from_hours we have the same issue BurntSushi presented scaled down to leap seconds as the ambiguity lies in misinterpreting Duration for a human offset that corrects for leap seconds.


This is way more unlikely to be a problem. Even if we could end up just saying the programmer was wrong and had a fundamental misunderstanding of what Duration stands for, it wouldn't inconvenience people depending on the buggy program too much. Failing to account for the extra second at 23:59:60 or the missing 23:59:59 wastes less time than reading this comment.

Also, we may not even have more leap seconds in the future due to a decrease on the Earth's rotation cancelling it1.

Footnotes

  1. https://en.wikipedia.org/wiki/Leap_second#Procedure

@ChrisDenton
Copy link
Member

I don't think there's any need to play devil's advocate nor a reason to continue blocking stabilizing from_mins and from_hours, which seems to be acceptable to everyone so far.

@Dietr1ch
Copy link

Dietr1ch commented Apr 18, 2025

@djc are you open to gut this to get from_mins and from_hours out?

I truly believe we should be free to get all of it, but I'd rather see some progress than waiting on a DateTime implementation getting to std.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests