]>
git.proxmox.com Git - rustc.git/blob - src/libstd/sys/windows/time.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
17 use sys_common
::mul_div_u64
;
20 const NANOS_PER_SEC
: u64 = 1_000_000_000;
21 const INTERVALS_PER_SEC
: u64 = NANOS_PER_SEC
/ 100;
23 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
28 #[derive(Copy, Clone)]
29 pub struct SystemTime
{
33 const INTERVALS_TO_UNIX_EPOCH
: u64 = 11_644_473_600 * INTERVALS_PER_SEC
;
35 pub const UNIX_EPOCH
: SystemTime
= SystemTime
{
37 dwLowDateTime
: INTERVALS_TO_UNIX_EPOCH
as u32,
38 dwHighDateTime
: (INTERVALS_TO_UNIX_EPOCH
>> 32) as u32,
43 pub fn now() -> Instant
{
44 let mut t
= Instant { t: 0 }
;
46 c
::QueryPerformanceCounter(&mut t
.t
)
51 pub fn sub_instant(&self, other
: &Instant
) -> Duration
{
52 // Values which are +- 1 need to be considered as basically the same
53 // units in time due to various measurement oddities, according to
57 // https://msdn.microsoft.com/en-us/library/windows/desktop
58 // /dn553408%28v=vs.85%29.aspx#guidance
59 if other
.t
> self.t
&& other
.t
- self.t
== 1 {
60 return Duration
::new(0, 0)
62 let diff
= (self.t
as u64).checked_sub(other
.t
as u64)
63 .expect("specified instant was later than \
65 let nanos
= mul_div_u64(diff
, NANOS_PER_SEC
, frequency() as u64);
66 Duration
::new(nanos
/ NANOS_PER_SEC
, (nanos
% NANOS_PER_SEC
) as u32)
69 pub fn add_duration(&self, other
: &Duration
) -> Instant
{
70 let freq
= frequency() as u64;
71 let t
= other
.as_secs().checked_mul(freq
).and_then(|i
| {
72 (self.t
as u64).checked_add(i
)
74 i
.checked_add(mul_div_u64(other
.subsec_nanos() as u64, freq
,
76 }).expect("overflow when adding duration to time");
78 t
: t
as c
::LARGE_INTEGER
,
82 pub fn sub_duration(&self, other
: &Duration
) -> Instant
{
83 let freq
= frequency() as u64;
84 let t
= other
.as_secs().checked_mul(freq
).and_then(|i
| {
85 (self.t
as u64).checked_sub(i
)
87 i
.checked_sub(mul_div_u64(other
.subsec_nanos() as u64, freq
,
89 }).expect("overflow when subtracting duration from time");
91 t
: t
as c
::LARGE_INTEGER
,
97 pub fn now() -> SystemTime
{
99 let mut t
: SystemTime
= mem
::zeroed();
100 c
::GetSystemTimeAsFileTime(&mut t
.t
);
105 fn from_intervals(intervals
: i64) -> SystemTime
{
108 dwLowDateTime
: intervals
as c
::DWORD
,
109 dwHighDateTime
: (intervals
>> 32) as c
::DWORD
,
114 fn intervals(&self) -> i64 {
115 (self.t
.dwLowDateTime
as i64) | ((self.t
.dwHighDateTime
as i64) << 32)
118 pub fn sub_time(&self, other
: &SystemTime
) -> Result
<Duration
, Duration
> {
119 let me
= self.intervals();
120 let other
= other
.intervals();
122 Ok(intervals2dur((me
- other
) as u64))
124 Err(intervals2dur((other
- me
) as u64))
128 pub fn add_duration(&self, other
: &Duration
) -> SystemTime
{
129 let intervals
= self.intervals().checked_add(dur2intervals(other
))
130 .expect("overflow when adding duration to time");
131 SystemTime
::from_intervals(intervals
)
134 pub fn sub_duration(&self, other
: &Duration
) -> SystemTime
{
135 let intervals
= self.intervals().checked_sub(dur2intervals(other
))
136 .expect("overflow when subtracting from time");
137 SystemTime
::from_intervals(intervals
)
141 impl PartialEq
for SystemTime
{
142 fn eq(&self, other
: &SystemTime
) -> bool
{
143 self.intervals() == other
.intervals()
147 impl Eq
for SystemTime {}
149 impl PartialOrd
for SystemTime
{
150 fn partial_cmp(&self, other
: &SystemTime
) -> Option
<Ordering
> {
151 Some(self.cmp(other
))
155 impl Ord
for SystemTime
{
156 fn cmp(&self, other
: &SystemTime
) -> Ordering
{
157 self.intervals().cmp(&other
.intervals())
161 impl fmt
::Debug
for SystemTime
{
162 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
163 f
.debug_struct("SystemTime")
164 .field("intervals", &self.intervals())
169 fn dur2intervals(d
: &Duration
) -> i64 {
170 d
.as_secs().checked_mul(INTERVALS_PER_SEC
).and_then(|i
| {
171 i
.checked_add(d
.subsec_nanos() as u64 / 100)
172 }).expect("overflow when converting duration to intervals") as i64
175 fn intervals2dur(intervals
: u64) -> Duration
{
176 Duration
::new(intervals
/ INTERVALS_PER_SEC
,
177 ((intervals
% INTERVALS_PER_SEC
) * 100) as u32)
180 fn frequency() -> c
::LARGE_INTEGER
{
181 static mut FREQUENCY
: c
::LARGE_INTEGER
= 0;
182 static ONCE
: Once
= Once
::new();
186 cvt(c
::QueryPerformanceFrequency(&mut FREQUENCY
)).unwrap();