Change:
Tracking issue for
One question raised during review is what representation these types should have on each platform. Currently they all have the native representation (e.g. , , etc) as this keeps lossless information as long as possible. As a consequence, however, issues like come up where the types have the property that basic algebra does not work on them. For example may be true (along with other various properties). The reason for this is that the resolution of the native representation varies among platforms, meaning that small increments aren't actually representable. I think_ that having a representation would fix this, but it is a divergence from the platform types and now if a is ever handed back to the standard library it'd have to do more conversions. May be worth it though?
Is there intended to be a public constructor for any of these, or make public as well? This API as is doesn't provide any way to represent a time that isn't relative to . It'd be great if there was a std library type that Diesel could return for database columns.
It’s a bit convoluted, but you can construct a with , for example.
Does make sense as the type to return from a database column? It seems to imply things which are incorrect. seems more appropriate.
Yeah as mentioned construction is intended to not be possible for the opaque type and done via the epoch anchor for . I'd probably suggest using for database interactions (are those stored as seconds-since-epoch?) or perhaps using an external library which also tracks extra information like a time zone.
They're stored as microseconds since 2000, so there would potentially be 2037 problems when converting.
Ah ok, in that case (especially if there's no extra time zone data or anything like that) I'd just create something like:
I support for this to Diesel in A note on the API from that -- The lack of negative durations makes constructing arbitrary times really painful, though I understand the reasoning that went into that. However, using for time comparison felt odd to me. It makes sense if you only expect monotonic time for use with , but it feels odd to use otherwise. Perhaps it would make sense to add another method or similar name, which returns an enum of either or ?
Very interesting! It's true that the APIs weren't necessarily designed initially with ergonomics as the primary feature, but rather correctness in terms of not omitting various oddities here and there. It's an interesting point though that and how it's more tailored towards timing operations rather than synthesizing new timestamps. There may be some slight tweaks that make it a little more amenable to this kind of operation.
being non-negative make sense (for the reasons given in the RFC), but I’m starting to think we should also have a type that represents a "signed" duration.
cc
My original design did indeed have a Signed Duration, but wanted to see more concrete justification. how do you feel now? On Mon, Dec 7, 2015, 6:37 AM Aaron Turon wrote:
In short, the justification is: if the way to convert to/from something the outside world can understand is to do arithmetic with an epoch constant, you’re gonna want to deal with (possibly) negative durations.
I'm not opposed to a sign duration type, and agree with that we'll still have achieved the basic goal by making the "default" duration nonnegative. Perhaps we can usefully prototype this out of tree.
I don’t really like the name , but I don’t have another suggestion. Although it would probably have to duplicate much of ’s own code, making that new type a struct that uses internally instead of is probably more natural than which is roughly the return type of
I experimented with converting over to using rather than libtime, and it went pretty smoothly: One note I do have is that for whatever reason, I found hard to intuitively reason about with respect to which should go where. Not totally sure if another name would be better though.
Would be better?
Might be, yeah.
What about duration_since? On Thu, Jan 7, 2016, 1:03 PM Steven Fackler wrote:
seems slightly off to me for reasons that I can't really explain. I assume that we don't just want a impl because of the panic if you get the ordering wrong? I kind of think that's the right way to go - unsigned int subtraction will overflow in debug builds if you get it backwards so it wouldn't be totally unexpected.
:bell: This issue is now entering its cycle final comment period to be stabilization in 1.8 :bell: The libs team agrees that the method can likely use a rename, and we're curious for other opinions as well (including using trait impls like ).
Greater than or equal to. There is no uniqueness guarantee.
I'd like to re-raise the issue of renaming that was brought up in the RFC discussion. My vote would be to rename to or . My biggest concern with the name is that it's not clear how it relates to . In reality they are both 'times', or instances in time, but the names do not make that clear. Additionally, the C++ API names them and , it would be nice to be in line with that. Another possibility is to rename to , but in practice it's difficult to guarantee steady time. The C++ standard specifies the steady time guarantee, but in practice the implementations fall short. If it's determined in the future that a steady clock is possible, then could be as an additional type.
note that the name is rather than , but I'm not sure if that affects what you're thinking much?
Sorry about that. But yes, I have the same issues with as I do with .
I'm also somewhat sympathetic to naming, specifically if we end up having a couple of clocks we'd probably want them all consistently named. Right now the names and don't share much similarity, and a pattern of seems reasonable-ish to start out at least.
I'm pretty uneasy with or , because we really want people to reach for this time first (say, when doing benchmarking), and just feels more niche and less friendly than . Instead of trying to find a way to make the two types appear to have parity, I'd rather find a name for that helps to indicate the caveats, and use for .
I agree with here. The name implies that it's monotonic. Time going backwards is the exception, not the rule (assuming the laws of physics as we know them hold. Dealing with computers which are traveling faster than the speed of light probably requires a separate RFC)
is certainly a better name than . That being said, I want to continue making the case for . This can go both ways. Ultimately you can't save all parties from their own ignorance by anointing one clock or another. It's better to put the two clock types on equal footing, and leave the education up to the documentation. The two types do have parity. They are both clocks which provide measurements. Neither is perfect, neither is strictly superior, and in any given situation it's likely that only one of them can appropriately be used. It also implies other properties: steadiness, not jumping forwards, that measurements can be compared across hosts, etc. None of the properties are guaranteed or provided by .
One more thought. A monotonic clock is not sufficient for benchmarking, the clock should also be steady. As a trivial example, a logical clock is monotonic but would be inappropriate for benchmarking. Perhaps the type should be , with the guarantee that it is as steady as the best clock on the platform.
although suffers from a stuttering problem, I'd be slightly more comfortable with the name over indeed!
Just re-export it from ! :trollface:
I've been using time2 in one of my projects, and I've been getting panics from "overflow when subtracting Durations". Unfortunately I haven't been able to repro this myself, but one of the users of my code has been getting it sporadically. I haven't been able to tell which subtraction could be causing them (they all look fine), and I've yet to get a backtrace back. I think its a bit of an ergonomic issue for subtraction to panic; if we want to disallow negative Durations, then it seems to me that subtraction should return a or .
The libs team discussed this during triage yesterday and we reached a few conclusions: We decided to stick with the name over the alternatives of or just . As the term seemed a bit niche, and we felt that the name was a bit "too sweet" and also may convey the wrong perception of a wall clock time, for example. Additionally, we felt that was actually pretty representative of what it was, an instant in time. We'll add to as it basically already supports it and is somewhat more readable than the method version. The method will be renamed to
Ah, and the other conclusion was to also stabilize everything, which is probably worth mentioning!

Discussion:
mod tests { use super::{Instant, SystemTime, Duration, UNIX_EPOCH}; <ins> macro_rules! assert_almost_eq { ($a:expr, $b:expr) => ({ let (a, b) = ($a, $b); if a != b { let (a, b) = if a > b {(a, b)} else {(b, a)}; assert!(a - Duration::new(0, 1) <= b); } }) } </ins> #[test] fn instant_monotonic() { let a = Instant::now();

let a = Instant::now(); let b = Instant::now(); let dur = b.duration_from_earlier(a); <del> assert_eq!(b - dur, a); assert_eq!(a + dur, b); </del> <ins> assert_almost_eq!(b - dur, a); assert_almost_eq!(a + dur, b); </ins> let second = Duration::new(1, 0); <del> assert_eq!(a - second + second, a); </del> <ins> assert_almost_eq!(a - second + second, a); </ins> } #[test]

let b = SystemTime::now(); match b.duration_from_earlier(a) { Ok(dur) if dur == Duration::new(0, 0) => { <del> assert_eq!(a, b); </del> <ins> assert_almost_eq!(a, b); </ins> } Ok(dur) => { assert!(b > a); <del> assert_eq!(b - dur, a); assert_eq!(a + dur, b); </del> <ins> assert_almost_eq!(b - dur, a); assert_almost_eq!(a + dur, b); </ins> } Err(dur) => { let dur = dur.duration(); assert!(a > b); <del> assert_eq!(b + dur, a); assert_eq!(b - dur, a); </del> <ins> assert_almost_eq!(b + dur, a); assert_almost_eq!(b - dur, a); </ins> } } let second = Duration::new(1, 0); <del> assert_eq!(a.duration_from_earlier(a - second).unwrap(), second); assert_eq!(a.duration_from_earlier(a + second).unwrap_err().duration(), second); </del> <ins> assert_almost_eq!(a.duration_from_earlier(a - second).unwrap(), second); assert_almost_eq!(a.duration_from_earlier(a + second).unwrap_err() .duration(), second); </ins> <del> assert_eq!(a - second + second, a); </del> <ins> assert_almost_eq!(a - second + second, a); </ins> let eighty_years = second * 60 * 60 * 24 * 365 * 80; <del> assert_eq!(a - eighty_years + eighty_years, a); assert_eq!(a - (eighty_years * 10) + (eighty_years * 10), a); </del> <ins> assert_almost_eq!(a - eighty_years + eighty_years, a); assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a); </ins> } #[test]