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

Improvements to the Time APIs #1288

Merged
merged 1 commit into from Nov 16, 2015

Conversation

Projects
None yet
@wycats
Copy link
Contributor

wycats commented Sep 21, 2015

@nrc nrc added the T-libs label Sep 21, 2015


It provides convenience methods for constructing Durations from larger units
of time (minutes, hours, days), but gives them names like
`Duration.from_standard_hour`. A standard hour is 3600 seconds, regardless of

This comment has been minimized.

@nagisa

nagisa Sep 21, 2015

Contributor

regardless of…?

Asking for an amount of time elapsed from a given `SystemTime` is a very common
operation that is guaranteed to produce a positive `Duration`. Asking for the
difference between an earlier and a later `SystemTime` also produces a positive
`Duration` when used correctly.

This comment has been minimized.

@nagisa

nagisa Sep 21, 2015

Contributor

s/SystemTime/ProcessTime/ in this paragraph?

This comment has been minimized.

@wycats

wycats Sep 21, 2015

Author Contributor

Yep!

optimizes for the broadly useful positive `Duration`.

```rs
impl SystemTime {

This comment has been minimized.

@nagisa

nagisa Sep 21, 2015

Contributor

ProcessTime?

/// Panics if `earlier` is later than &self.
/// Because SystemTime is monotonic, the only ime that `earlier` should be
/// a later time is a bug in your code.
pub fn duration_from_earlier(&self, earlier: SystemTime) -> SystemTime;

This comment has been minimized.

@nagisa

nagisa Sep 21, 2015

Contributor

ProcessTime

pub fn elapsed(&self) -> Duration;
}

impl Add<Duration> for SystemTime {

This comment has been minimized.

@nagisa

nagisa Sep 21, 2015

Contributor

ProcessTime

type Output = SystemTime;
}

impl Sub<Duration> for SystemTime {

This comment has been minimized.

@nagisa

nagisa Sep 21, 2015

Contributor

ProcessTime


While I have nothing against it; just noting inconsistency, in earlier paragraphs you allow

subtract a ProcessTime from a later ProcessTime, producing a Duration

and not this.

This comment has been minimized.

@wycats

wycats Sep 21, 2015

Author Contributor

That is referring to duration_from_earlier, not the Sub operator 😄

This comment has been minimized.

@gsingh93

gsingh93 Sep 21, 2015

But duration_from_earlier doesn't seem to produce a Duration either?

pub fn duration_from_earlier(&self, earlier: SystemTime) -> Result<Duration, ()>;

/// Returns an `Err` if &self is later than the current system time.
pub fn elapsed(&self) -> Result<Duration, ()>;

This comment has been minimized.

@nagisa

nagisa Sep 21, 2015

Contributor

Err = () is not sufficient, because system time APIs (on UNIX) might error-out for their own reasons.

@wycats

This comment has been minimized.

Copy link
Contributor Author

wycats commented Sep 21, 2015

@nagisa thanks for the early feedback. I'll correct these typos ASAP!

the timeframe of the process it was created in.

> In this context, monotonic means that a timestamp created later in real-world
> time will always be larger than a timestamp created earlier in real-world

This comment has been minimized.

@sfackler

sfackler Sep 21, 2015

Member

Pedantically speaking, "no smaller than", since you might pull the time twice within the same tick.

impl SystemTime {
/// Panics if `earlier` is later than &self.
/// Because SystemTime is monotonic, the only ime that `earlier` should be
/// a later time is a bug in your code.

This comment has been minimized.

@sfackler

sfackler Sep 21, 2015

Member

Are we going to guarantee that the time will "never" overflow? Windows guarantees that overflow won't happen for at least ~200 years of uptime, but I'm not sure about OSX and Linux.

# Alternatives

One alternative design would be to attempt to have a single unified time
type. The rationale for now doing so is explained under Drawbacks.

This comment has been minimized.

@leodasvacas

leodasvacas Sep 21, 2015

Don't you mean "rationale for not doing so"?

types and operations.

First of all, with the exception of instants created in the rutime of a single
process, instants are not monotonic. A simple example of this is that if a

This comment has been minimized.

@jmesmon

jmesmon Sep 21, 2015

Ok, so we're talking about the proposed API here? Because both Posix and windows provide functions to get a monotonic system time (clock_gettime + CLOCK_MONOTONIC or GetTickCount64()/GetTickCount()).

Might want to clearly delineate where we're talking about actual system restrictions vs restrictions that just occur in the Rust api.

The simple example happens to be true because (generally) one cannot specify the clock used to generate a file timestamp.

Edit: my confusion here might be due to thinking ProcessTime refers to the amount of time a particular process has run (ie: cpu time) rather than just being monotonic time. If that is the intention, it might make sense to avoid the proposed naming.

Edit2: to illustrate why this is confusing (assuming ProcessTime is meant to mean "some type of monotonic time"), consider what posix says about (CLOCK_MONOTONIC)[http://pubs.opengroup.org/onlinepubs/9699919799/]:

This clock represents the monotonic clock for the system

And also consdier what windows says about (GetTickCount64())[https://msdn.microsoft.com/en-us/library/windows/desktop/ms724411(v=vs.85).aspx]:

milliseconds that have elapsed since the system was started.

No mention of it being per-process there.

Does rust intend to have it's monotonic time be per-process? If so, why?
If not (and I haven't completely misinterpreted things), I strongly recommend a different name.

This comment has been minimized.

@eternaleye

eternaleye Sep 23, 2015

There's also that there are multiple kinds of monotonic time on some systems.

In particular, while CLOCK_MONOTONIC generates comparable and orderable instants, it does not generate comparable durations because it is still affected by NTP's ability to alter the length of a second. Linux at least has CLOCK_MONOTONIC_RAW (whose ticks are of constant length), but it makes no guarantee of the relationship between its units and human-meaningful ones.

In addition, suspend/hibernate is not counted for CLOCK_MONOTONIC, so durations from it are even more suspect - but Linux has the (underdocumented) CLOCK_BOOTTIME, which does count that... however, it isn't clear what its guarantees on the length of a tick are (consistent vs. meaningful).

Yes, this is in fact worth curling up in a corner over. No, it likely doesn't get better.

EDIT:

Personally, what I wish the platform provided was something akin to three calls:

booted() -> TAI nanoseconds
offset(kind) -> Consistent-length ticks since booted()
scale() -> Ratio ns/ticks

where 'kind' is one of "run" or "boot", respectively meaning actual runtime (CLOCK_MONOTONIC_RAW) or external time since boot (a hypothetical CLOCK_BOOTTIME_RAW) respectively.

The workflow would then be:

 // take measurements
let start = offset(kind);
do_thing();
let end = offset(kind);
// Get a comparable duration
let duration = end - start;
// Get _coherent_ view of what that means in real units
let ratio = scale();
println!("do_thing() took {} nanoseconds", duration * ratio);
// Get the beginning of time, to format as human-readable instants
let base = booted();
println!(
    "It began at {:date} and finished at {:date}",
    base + start * ratio; base + end * ratio
);

One can at least approximate those on Linux systems in some cases:

  • booted(): CLOCK_TAI - CLOCK_MONOTONIC
  • offset(run): CLOCK_MONOTONIC_RAW
  • scale(): possibly CLOCK_MONOTONIC / CLOCK_MONOTONIC_RAW, but that relies on NTP's second-slewing averaging out to a second, which is likely optimistic when it also uses it to correct small initial errors. It also doesn't work for BOOTTIME because there is no _RAW variant. Eugh. :/
program creates two files sequentially, it cannot assume that the creation time
of the second file is later than the creation time of the first file.

This is because NTP (the network time protocol) can arbitrarily change the

This comment has been minimized.

@jmesmon

jmesmon Sep 21, 2015

Might be a good idea to clarify to:

NTP (the network time protocol) and any process/user with sufficient privileges

unlikely programmers are to consider "12:00:60" as a valid time.

Certain kinds of seemingly simple operations may not make sense in
all cases. For example, adding "1 year" to February 29, 2012 would produce

This comment has been minimized.

@jmesmon

jmesmon Sep 21, 2015

I'd replace would with could or might, unless we intend to have the Rust api generate invalid dates. (The subtext here is that there are other ways to resolve these than generating invalid dates)

* ask for an amount of time elapsed since a `ProcessTime`, producing a `Duration`

Asking for an amount of time elapsed from a given `ProcessTime` is a very common
operation that is guaranteed to produce a positive `Duration`. Asking for the

This comment has been minimized.

@jmesmon

jmesmon Sep 21, 2015

Should this really be positive? Or just non-negative? (ie: might help to clarify if a elapsed time can be 0)


The most important caveat of `SystemTime` is that it is **not monotonic**. This
means that you can save a file to the file system, then save another file to
the file system, **and the second file has an `mtime` earlier than the second**.

This comment has been minimized.

@jmesmon

jmesmon Sep 21, 2015

s/has an/could have an/

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Sep 21, 2015

Where should Duration::span go? An associated function of ProcessTime? A free function? (Having it in a single expression with a closure is sometimes nicer than let start = ProcessTime::now(); /* do something */; start.elapsed()

By the way, should ProcessTime and SystemTime have now() constructors?

@retep998

This comment has been minimized.

Copy link
Member

retep998 commented Sep 21, 2015

I like having the distinction between monotonic and system time.

@aturon

This comment has been minimized.

Copy link
Member

aturon commented Sep 21, 2015

@asb

This comment has been minimized.

Copy link

asb commented Sep 22, 2015

Might it be worth contrasting this API with that offered by e.g. Jodatime,
Haskell's time library (
https://www.reddit.com/r/haskell/comments/3j2o7a/finally_a_great_tutorial_for_the_time_library/),
Go's time library, ...?

On 22 September 2015 at 00:05, Aaron Turon notifications@github.com wrote:

cc @lifthrasiir https://github.com/lifthrasiir


Reply to this email directly or view it on GitHub
#1288 (comment).

@yazaddaruvala

This comment has been minimized.

Copy link

yazaddaruvala commented Sep 23, 2015

Hopefully not just JodaTime but also java.time
Which is a redesign of JodaTime, by its author, for Java 8

The article is clearly really old, but might help this design:
http://blog.joda.org/2009/11/why-jsr-310-isn-joda-time_4941.html

@yazaddaruvala

This comment has been minimized.

Copy link

yazaddaruvala commented Sep 23, 2015

@wycats from the wording in the current draft it seems like the biggest problem isn't actually monotonicity of time but the creation of negative durations. If there are no other issues with time lacking monotonicity, one alternative I haven't seen discussed but would like to mention is to instead split up Duration.

SystemTime, ProcessTime -> Instant
Duration -> uDuration, iDuration (aka UnsignedDuration, SignedDuration)

Apart from naming conventions, I kinda like the consistency it has with numbers.
APIs that don't deal with negative 64bit numbers only accept u64.
APIs that don't deal with negative durations only accept UnsignedDuration.

I don't think it even changes all that much:

impl SignedDuration {
  // Maybe use `as` for conversions?
  pub fn to_unsigned(&self) -> Result<UnsignedDuration, Error>;

  ...
}

impl Instant {
  pub fn duration_from(&self, other: Instant) -> SignedDuration;

  pub fn duration_from_now(&self) -> SignedDuration;

  /// Panics if `earlier` is later than &self.
  /// Because ProcessTime is monotonic, the only time that `earlier` should be
  /// a later time is a bug in your code.
  pub fn duration_from_earlier(&self, earlier: Instant) -> UnsignedDuration {
    self.duration_from(earlier).to_unsigned().expect('Sorry, that wasn't earlier..')
  }

  /// Panics if self is later than the current time
  pub fn elapsed(&self) -> Duration;
}

Pros:
Duration could be a trait, allowing generic extensions like impl formatting, and user defined Durations (i.e. BigIntDuration)
Allows for use of SignedDuration when appropriate
Given an understanding of Rust's numbers, SignedDuration vs UnsignedDuration might be more intuitive, while ProcessTime vs SystemTime would require a tiny explanation

Cons:
Leaving methods like duration_from_earlier and elapsed on Instant may cause unexpected prod bugs which we are trying to avoid. With some ergonomic sacrifice, only expose duration_from/_now and let users handle conversion.
How should a SignedDuration convert to an UnsignedDuration?

Let me know what downsides I'm not aware of or am currently missing. Thanks.

P.S. After writing this up, if it helps, I did find: https://internals.rust-lang.org/t/unsigned-version-of-duration/893

@Veedrac

This comment has been minimized.

Copy link

Veedrac commented Sep 23, 2015

I have nothing against a positive-first API, but one should not ignore negative durations either. That said, I can't really think of a case where you'd want signed durations and not want to branch off their direction.

So my suggestion is that the Result<Duration, SystemTimeError> should be changed to Result<Duration, Duration>, where the later Duration is the negative of the difference. This makes it clear that the only case SystemTimeError was accounting for is time travel, and makes it really obvious how to deal with negative cases. When you do want a SignedDuration, Result<Duration, Duration> is only a little bigger (and could reasonably be optimized to the same size in the future by re-using padding).

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Sep 24, 2015

I don't think libstd should contain a calendar - these contain lots of subjective edge cases. However, we probably want some form of absolute time for cross-system timestamps (we would need to choose between classic UNIX, UTS, or TAI). Leap-second-aware format conversions would be nice.

@eternaleye

This comment has been minimized.

Copy link

eternaleye commented Sep 24, 2015

Personally, I strongly favor TAI for cross-system times, for the following reasons:

  • POSIX time is incoherent-as-specified, as it mandates both an 86,400-second day and that it is UTC, which due to leap seconds does not have an 86,400-second day
  • UTC, strictly speaking, only applies to the string-based format in which "XX:YY:60" can be represented
  • The duration between two UTC times can change at any point before the latter of them has passed, due to leap seconds being awful
@cristicbz

This comment has been minimized.

Copy link

cristicbz commented Sep 25, 2015

Two minor suggestions:

    pub struct StdHours(pub u64);
    pub struct StdMinutes(pub u64);
    // ...
    impl From<StdHours> for Duration {
        // ...
    }
    // ...

Then conversions become as simple as: Duration::from(StdHours(3)) and it ensures that I can store strongly typed numbers of hours/minutes etc. without getting them mixed up.

What do you think?

Edit: One worry might be panicking From conversions. I don't have a problem with that (since I don't have a problem with n as u32 panicking for large values of n), but I know some people might.

@wycats

This comment has been minimized.

Copy link
Contributor Author

wycats commented Sep 25, 2015

Replying to @cristicbz (more later on other comments):

I don't love MonotonicTime since I expect this to be the primary API developers use for things like benchmarks, and an obscure name might put them off.

The point about being allowed to use BOOT_TIME is good, though. Can you think of a friendly name that communicates monotonicity? TimeThatObeysTheLawsOfPhysics :p

I don't object to conversions at first glance and agree that they read nicely, provide nice ergonomics for mixing, and make it easy to avoid mistakes.

I'll let others weigh in on the panicking issue before I form a strong opinion though :) @aturon?

@eternaleye

This comment has been minimized.

Copy link

eternaleye commented Sep 25, 2015

I think that C++'s steady_time would be effectively perfect (as SteadyTime) for CLOCK_MONOTONIC_RAW, but for CLOCK_MONOTONIC there's some difficulty. I think SequentialTime is about as good as it can get:

  • To a first approximation, sequential : monotonic :: ordinal : cardinal
  • Unlike SteadyTime it does not imply the intervals are identical
  • Sequential is a much more common word than monotonic

For CLOCK_BOOTTIME, there's the complication that it behaves like CLOCK_MONOTONIC in every way, except that it also covers time suspended. Thus, both have equal claim to SequentialTime, but constructions like SequentialTimeWithoutSuspended are, to put it frankly, ugly as sin.

As far as use cases go, what should each be used for?

  • CLOCK_MONOTONIC_RAW - anything that needs to (computationally) compare intervals/durations for relative size within a single machine. Benchmarks are a big one -"X took 1.6x as long as Y" requires constant-length ticks.
  • CLOCK_BOOTTIME - Anything that wants to give relative times in human units that correspond to external events ("Your last sync was six hours ago")
  • CLOCK_MONOTONIC - Anything that wants to give relative times in human units that correspond to internal events ("This process has been hung for five minutes. Kill it?")

Notably not covered:

  • Intervals that can be both compared and converted to human units. The system APIs just don't exist.
  • Intervals that can be compared across machines. This is not only difficult in practice, it's always going to have insoluble limitations due to physics. CLOCK_MONOTONIC is probably as good as we can get since its seconds should be roughly one SI second, but it's still not very good at all.
  • Intervals whose endpoints lie on different machines. CLOCK_TAI is probably the best that can be done here, and only if we assume accurately-synced clocks on both. (At least TAI lets us ignore leap seconds once we've got the Instant in our hands, unlike UTC/CLOCK_REALTIME).
@nagisa

This comment has been minimized.

Copy link
Contributor

nagisa commented Nov 4, 2015

Is there any indication of a fixed upper-bound on the non-monotonicity, such that it could be avoided by masking low bits?

That’s not a valid solution, is it?

Regarding @vadimcn’s link, virtualised environments are a pretty interesting use case/test which might uncover a whole can of worms with every platform we support (and possibly various different processors that might or might not have “interesting” clocks, if any), since they might not allow virtualised kernel to access hardware directly and other small details.

@eternaleye

This comment has been minimized.

Copy link

eternaleye commented Nov 4, 2015

@nagisa

I was hoping it was like the architectural constraints/guarantees for RDTIME on the RISC-V architecture, which permits 1 tick of inconsistency between cores.

@vadimcn

This comment has been minimized.

Copy link
Contributor

vadimcn commented Nov 4, 2015

@eternaleye: I don't recall seeing the 2-3s number anywhere. I would guess that non-monotonicity is on the order of as few ticks (as returned by QueryPerformanceFrequency(), but who knows... Obviously, Microsoft did not intend there to be any non-monotonicity, so it's a hardware/HAL bug.
I don't think we should try to paper it over, though I'd be in favor of providing APIs that help in dealing with such errors (for example deriving a non-negative timeout from two Instants).

@eternaleye

This comment has been minimized.

Copy link

eternaleye commented Nov 4, 2015

@vadimcn

I don't recall seeing the 2-3s number anywhere.

It's a comment by the original reporter in response to a question about the magnitude.

What is the value of ElapsedMilliseconds when negative? – Michael Haren Jun 17 '09 at 17:04

On my VM it around -3000 to -2000 – Vadym Stetsiak Jun 17 '09 at 17:11

@vadimcn

This comment has been minimized.

Copy link
Contributor

vadimcn commented Nov 4, 2015

@eternaleye: he probably meant 'ticks', not 'milliseconds'.

@eternaleye

This comment has been minimized.

Copy link

eternaleye commented Nov 4, 2015

@vadimcn

ElapsedMilliseconds is consistently used - both in the original post's code example and the comments.

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Nov 4, 2015

@eternaleye

Yeah - having a UNIX_EPOCH without specifying whether we're counting SI or UT1 is stupid. I suppose we should just say we are counting "unspecified-UT1" for this API.

@kryptan

This comment has been minimized.

Copy link

kryptan commented Nov 4, 2015

Seems that no one mentioned but according to wikipedia the desicion whether to keep or abolish leap seconds will be made at World Radiocommunication Conference which is scheduled for November 2–27 (i.e. it is happening now). Indeed, their page states:

WRC-15 will address a number of key issues, in particular:

  • ...
  • ... the feasibility of achieving a continuous reference time-scale (UTC) with the possible suppression of the “leap second”

Lets hope that they will do the right thing.

`Duration` when used correctly.

This design does not assume that negative `Duration`s are never useful, but
rather than the most common uses of `Duration` do not have a meaningful

This comment has been minimized.

@boxofrox

boxofrox Nov 8, 2015

Typo: s/rather than/rather that/

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Nov 16, 2015

The libs team discussed this RFC during triage last week and after some final clarifications we've decided to merge. The last pieces were indicating that Instant is not always increasing, but rather never decreasing, and guaranteeing that SystemTime is UTC.

For now we've decided to take the conservative route of not trying to exhaustively specify all aspects of the two types here, but as usual there will be a period of #[unstable] for these implementations in the standard library where final tweaks and changes can be made (especially around documentation and such). The implementations are likely to follow what already exists in the time crate as well as similar C++ implementations.

Thanks again for all the discussion everyone!

@alexcrichton alexcrichton merged commit d8133de into rust-lang:master Nov 16, 2015

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Nov 16, 2015

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Nov 17, 2015

std: Add Instant and SystemTime to std::time
This commit is an implementation of [RFC 1288][rfc] which adds two new unstable
types to the `std::time` module. The `Instant` type is used to represent
measurements of a monotonically increasing clock suitable for measuring time
withing a process for operations such as benchmarks or just the elapsed time to
do something. An `Instant` favors panicking when bugs are found as the bugs are
programmer errors rather than typical errors that can be encountered.

[rfc]: rust-lang/rfcs#1288

The `SystemTime` type is used to represent a system timestamp and is not
monotonic. Very few guarantees are provided about this measurement of the system
clock, but a fixed point in time (`UNIX_EPOCH`) is provided to learn about the
relative distance from this point for any particular time stamp.

This PR takes the same implementation strategy as the `time` crate on crates.io,
namely:

|  Platform  |  Instant                 |  SystemTime              |
|------------|--------------------------|--------------------------|
| Windows    | QueryPerformanceCounter  | GetSystemTimeAsFileTime  |
| OSX        | mach_absolute_time       | gettimeofday             |
| Unix       | CLOCK_MONOTONIC          | CLOCK_REALTIME           |

These implementations can perhaps be refined over time, but they currently
satisfy the requirements of the `Instant` and `SystemTime` types while also
being portable across implementations and revisions of each platform.

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Nov 17, 2015

std: Add Instant and SystemTime to std::time
This commit is an implementation of [RFC 1288][rfc] which adds two new unstable
types to the `std::time` module. The `Instant` type is used to represent
measurements of a monotonically increasing clock suitable for measuring time
withing a process for operations such as benchmarks or just the elapsed time to
do something. An `Instant` favors panicking when bugs are found as the bugs are
programmer errors rather than typical errors that can be encountered.

[rfc]: rust-lang/rfcs#1288

The `SystemTime` type is used to represent a system timestamp and is not
monotonic. Very few guarantees are provided about this measurement of the system
clock, but a fixed point in time (`UNIX_EPOCH`) is provided to learn about the
relative distance from this point for any particular time stamp.

This PR takes the same implementation strategy as the `time` crate on crates.io,
namely:

|  Platform  |  Instant                 |  SystemTime              |
|------------|--------------------------|--------------------------|
| Windows    | QueryPerformanceCounter  | GetSystemTimeAsFileTime  |
| OSX        | mach_absolute_time       | gettimeofday             |
| Unix       | CLOCK_MONOTONIC          | CLOCK_REALTIME           |

These implementations can perhaps be refined over time, but they currently
satisfy the requirements of the `Instant` and `SystemTime` types while also
being portable across implementations and revisions of each platform.

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Nov 17, 2015

std: Add Instant and SystemTime to std::time
This commit is an implementation of [RFC 1288][rfc] which adds two new unstable
types to the `std::time` module. The `Instant` type is used to represent
measurements of a monotonically increasing clock suitable for measuring time
withing a process for operations such as benchmarks or just the elapsed time to
do something. An `Instant` favors panicking when bugs are found as the bugs are
programmer errors rather than typical errors that can be encountered.

[rfc]: rust-lang/rfcs#1288

The `SystemTime` type is used to represent a system timestamp and is not
monotonic. Very few guarantees are provided about this measurement of the system
clock, but a fixed point in time (`UNIX_EPOCH`) is provided to learn about the
relative distance from this point for any particular time stamp.

This PR takes the same implementation strategy as the `time` crate on crates.io,
namely:

|  Platform  |  Instant                 |  SystemTime              |
|------------|--------------------------|--------------------------|
| Windows    | QueryPerformanceCounter  | GetSystemTimeAsFileTime  |
| OSX        | mach_absolute_time       | gettimeofday             |
| Unix       | CLOCK_MONOTONIC          | CLOCK_REALTIME           |

These implementations can perhaps be refined over time, but they currently
satisfy the requirements of the `Instant` and `SystemTime` types while also
being portable across implementations and revisions of each platform.

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Nov 17, 2015

std: Add Instant and SystemTime to std::time
This commit is an implementation of [RFC 1288][rfc] which adds two new unstable
types to the `std::time` module. The `Instant` type is used to represent
measurements of a monotonically increasing clock suitable for measuring time
withing a process for operations such as benchmarks or just the elapsed time to
do something. An `Instant` favors panicking when bugs are found as the bugs are
programmer errors rather than typical errors that can be encountered.

[rfc]: rust-lang/rfcs#1288

The `SystemTime` type is used to represent a system timestamp and is not
monotonic. Very few guarantees are provided about this measurement of the system
clock, but a fixed point in time (`UNIX_EPOCH`) is provided to learn about the
relative distance from this point for any particular time stamp.

This PR takes the same implementation strategy as the `time` crate on crates.io,
namely:

|  Platform  |  Instant                 |  SystemTime              |
|------------|--------------------------|--------------------------|
| Windows    | QueryPerformanceCounter  | GetSystemTimeAsFileTime  |
| OSX        | mach_absolute_time       | gettimeofday             |
| Unix       | CLOCK_MONOTONIC          | CLOCK_REALTIME           |

These implementations can perhaps be refined over time, but they currently
satisfy the requirements of the `Instant` and `SystemTime` types while also
being portable across implementations and revisions of each platform.

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Nov 17, 2015

std: Add Instant and SystemTime to std::time
This commit is an implementation of [RFC 1288][rfc] which adds two new unstable
types to the `std::time` module. The `Instant` type is used to represent
measurements of a monotonically increasing clock suitable for measuring time
withing a process for operations such as benchmarks or just the elapsed time to
do something. An `Instant` favors panicking when bugs are found as the bugs are
programmer errors rather than typical errors that can be encountered.

[rfc]: rust-lang/rfcs#1288

The `SystemTime` type is used to represent a system timestamp and is not
monotonic. Very few guarantees are provided about this measurement of the system
clock, but a fixed point in time (`UNIX_EPOCH`) is provided to learn about the
relative distance from this point for any particular time stamp.

This PR takes the same implementation strategy as the `time` crate on crates.io,
namely:

|  Platform  |  Instant                 |  SystemTime              |
|------------|--------------------------|--------------------------|
| Windows    | QueryPerformanceCounter  | GetSystemTimeAsFileTime  |
| OSX        | mach_absolute_time       | gettimeofday             |
| Unix       | CLOCK_MONOTONIC          | CLOCK_REALTIME           |

These implementations can perhaps be refined over time, but they currently
satisfy the requirements of the `Instant` and `SystemTime` types while also
being portable across implementations and revisions of each platform.

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Nov 17, 2015

std: Add Instant and SystemTime to std::time
This commit is an implementation of [RFC 1288][rfc] which adds two new unstable
types to the `std::time` module. The `Instant` type is used to represent
measurements of a monotonically increasing clock suitable for measuring time
withing a process for operations such as benchmarks or just the elapsed time to
do something. An `Instant` favors panicking when bugs are found as the bugs are
programmer errors rather than typical errors that can be encountered.

[rfc]: rust-lang/rfcs#1288

The `SystemTime` type is used to represent a system timestamp and is not
monotonic. Very few guarantees are provided about this measurement of the system
clock, but a fixed point in time (`UNIX_EPOCH`) is provided to learn about the
relative distance from this point for any particular time stamp.

This PR takes the same implementation strategy as the `time` crate on crates.io,
namely:

|  Platform  |  Instant                 |  SystemTime              |
|------------|--------------------------|--------------------------|
| Windows    | QueryPerformanceCounter  | GetSystemTimeAsFileTime  |
| OSX        | mach_absolute_time       | gettimeofday             |
| Unix       | CLOCK_MONOTONIC          | CLOCK_REALTIME           |

These implementations can perhaps be refined over time, but they currently
satisfy the requirements of the `Instant` and `SystemTime` types while also
being portable across implementations and revisions of each platform.
@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Nov 17, 2015

I've now got an implementation of this RFC, so if you'd like to take a look over it please feel free to leave a comment there!

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Nov 18, 2015

std: Add Instant and SystemTime to std::time
This commit is an implementation of [RFC 1288][rfc] which adds two new unstable
types to the `std::time` module. The `Instant` type is used to represent
measurements of a monotonically increasing clock suitable for measuring time
withing a process for operations such as benchmarks or just the elapsed time to
do something. An `Instant` favors panicking when bugs are found as the bugs are
programmer errors rather than typical errors that can be encountered.

[rfc]: rust-lang/rfcs#1288

The `SystemTime` type is used to represent a system timestamp and is not
monotonic. Very few guarantees are provided about this measurement of the system
clock, but a fixed point in time (`UNIX_EPOCH`) is provided to learn about the
relative distance from this point for any particular time stamp.

This PR takes the same implementation strategy as the `time` crate on crates.io,
namely:

|  Platform  |  Instant                 |  SystemTime              |
|------------|--------------------------|--------------------------|
| Windows    | QueryPerformanceCounter  | GetSystemTimeAsFileTime  |
| OSX        | mach_absolute_time       | gettimeofday             |
| Unix       | CLOCK_MONOTONIC          | CLOCK_REALTIME           |

These implementations can perhaps be refined over time, but they currently
satisfy the requirements of the `Instant` and `SystemTime` types while also
being portable across implementations and revisions of each platform.

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Nov 19, 2015

std: Add Instant and SystemTime to std::time
This commit is an implementation of [RFC 1288][rfc] which adds two new unstable
types to the `std::time` module. The `Instant` type is used to represent
measurements of a monotonically increasing clock suitable for measuring time
withing a process for operations such as benchmarks or just the elapsed time to
do something. An `Instant` favors panicking when bugs are found as the bugs are
programmer errors rather than typical errors that can be encountered.

[rfc]: rust-lang/rfcs#1288

The `SystemTime` type is used to represent a system timestamp and is not
monotonic. Very few guarantees are provided about this measurement of the system
clock, but a fixed point in time (`UNIX_EPOCH`) is provided to learn about the
relative distance from this point for any particular time stamp.

This PR takes the same implementation strategy as the `time` crate on crates.io,
namely:

|  Platform  |  Instant                 |  SystemTime              |
|------------|--------------------------|--------------------------|
| Windows    | QueryPerformanceCounter  | GetSystemTimeAsFileTime  |
| OSX        | mach_absolute_time       | gettimeofday             |
| Unix       | CLOCK_MONOTONIC          | CLOCK_REALTIME           |

These implementations can perhaps be refined over time, but they currently
satisfy the requirements of the `Instant` and `SystemTime` types while also
being portable across implementations and revisions of each platform.

bors added a commit to rust-lang/rust that referenced this pull request Nov 19, 2015

Auto merge of #29894 - alexcrichton:stdtime, r=brson
This commit is an implementation of [RFC 1288][rfc] which adds two new unstable
types to the `std::time` module. The `Instant` type is used to represent
measurements of a monotonically increasing clock suitable for measuring time
withing a process for operations such as benchmarks or just the elapsed time to
do something. An `Instant` favors panicking when bugs are found as the bugs are
programmer errors rather than typical errors that can be encountered.

[rfc]: rust-lang/rfcs#1288

The `SystemTime` type is used to represent a system timestamp and is not
monotonic. Very few guarantees are provided about this measurement of the system
clock, but a fixed point in time (`UNIX_EPOCH`) is provided to learn about the
relative distance from this point for any particular time stamp.

This PR takes the same implementation strategy as the `time` crate on crates.io,
namely:

|  Platform  |  Instant                 |  SystemTime              |
|------------|--------------------------|--------------------------|
| Windows    | QueryPerformanceCounter  | GetSystemTimeAsFileTime  |
| OSX        | mach_absolute_time       | gettimeofday             |
| Unix       | CLOCK_MONOTONIC          | CLOCK_REALTIME           |

These implementations can perhaps be refined over time, but they currently
satisfy the requirements of the `Instant` and `SystemTime` types while also
being portable across implementations and revisions of each platform.

cc #29866
@tioover

This comment has been minimized.

Copy link

tioover commented Jan 31, 2016

Why not implement Hash to Duration and Instant?

For example

use std::time::Instant;

#[derive(PartialEq, Eq, Hash, PartialOrd, Ord)]
struct ID {
    random: u32,
    instant: Instant,
}
@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Jan 31, 2016

@tioover Duration now implements Hash: rust-lang/rust#30818. The lack of an implementation for Instant is just an oversight - feel free to make a PR adding the impl.

Since this RFC has been merged, rust-lang/rust#29866 is the new place for discussion, by the way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.