2
2
3
3
use crate :: iso:: IsoDateTime ;
4
4
use crate :: provider:: TimeZoneProvider ;
5
- use crate :: sys :: SystemHooks ;
5
+ use crate :: time :: EpochNanoseconds ;
6
6
use crate :: TemporalResult ;
7
- use alloc:: string:: String ;
8
7
9
8
#[ cfg( feature = "sys" ) ]
10
- use crate :: sys :: DefaultSystemHooks ;
9
+ use alloc :: string :: String ;
11
10
12
11
use super :: {
13
12
calendar:: Calendar , timezone:: TimeZone , Instant , PlainDate , PlainDateTime , PlainTime ,
@@ -18,47 +17,61 @@ use super::{
18
17
pub struct Now ;
19
18
20
19
impl Now {
21
- pub fn instant_with_hooks ( system_hooks : & impl SystemHooks ) -> TemporalResult < Instant > {
22
- let epoch_nanoseconds = system_hooks. get_system_nanoseconds ( ) ?;
23
- Ok ( Instant :: from ( epoch_nanoseconds) )
24
- }
25
-
26
- pub fn system_time_zone_identifier_with_hooks (
27
- system_hooks : & impl SystemHooks ,
28
- ) -> TemporalResult < String > {
29
- system_hooks. get_system_time_zone ( )
20
+ pub fn instant_with_epoch_nanoseconds ( epoch_nanoseconds : EpochNanoseconds ) -> Instant {
21
+ Instant :: from ( epoch_nanoseconds)
30
22
}
31
23
32
- pub fn system_datetime_with_hooks_and_provider (
33
- time_zone : Option < TimeZone > ,
34
- system_hooks : & impl SystemHooks ,
24
+ /// Returns the current system `DateTime` based off the provided system args
25
+ ///
26
+ /// ## Order of operations
27
+ ///
28
+ /// The order of operations for this method requires the `GetSystemTimeZone` call
29
+ /// to occur prior to calling system time and resolving the `EpochNanoseconds`
30
+ /// value.
31
+ ///
32
+ /// A correct implementation will follow the following steps:
33
+ ///
34
+ /// 1. Resolve user input `TimeZone` with the `SystemTimeZone`.
35
+ /// 2. Get the `SystemNanoseconds`
36
+ ///
37
+ /// For an example implementation see [`Self::zoneddatetime_iso`]
38
+ ///
39
+ pub ( crate ) fn system_datetime_with_provider (
40
+ epoch_nanoseconds : EpochNanoseconds ,
41
+ timezone : TimeZone ,
35
42
provider : & impl TimeZoneProvider ,
36
43
) -> TemporalResult < IsoDateTime > {
37
44
// 1. If temporalTimeZoneLike is undefined, then
38
45
// a. Let timeZone be SystemTimeZoneIdentifier().
39
46
// 2. Else,
40
47
// a. Let timeZone be ? ToTemporalTimeZoneIdentifier(temporalTimeZoneLike).
41
- let tz = time_zone. unwrap_or ( TimeZone :: IanaIdentifier (
42
- system_hooks. get_system_time_zone ( ) ?,
43
- ) ) ;
44
48
// 3. Let epochNs be SystemUTCEpochNanoseconds().
45
- let epoch_ns = system_hooks. get_system_nanoseconds ( ) ?;
46
49
// 4. Return GetISODateTimeFor(timeZone, epochNs).
47
- tz . get_iso_datetime_for ( & Instant :: from ( epoch_ns ) , provider)
50
+ timezone . get_iso_datetime_for ( & Instant :: from ( epoch_nanoseconds ) , provider)
48
51
}
49
52
50
53
/// Returns the current system time as a `ZonedDateTime` with an ISO8601 calendar.
51
54
///
52
55
/// The time zone will be set to either the `TimeZone` if a value is provided, or
53
56
/// according to the system timezone if no value is provided.
54
- pub fn zoneddatetime_iso_with_hooks (
55
- timezone : Option < TimeZone > ,
56
- system_hooks : & impl SystemHooks ,
57
+ ///
58
+ /// ## Order of operations
59
+ ///
60
+ /// The order of operations for this method requires the `GetSystemTimeZone` call
61
+ /// to occur prior to calling system time and resolving the `EpochNanoseconds`
62
+ /// value.
63
+ ///
64
+ /// A correct implementation will follow the following steps:
65
+ ///
66
+ /// 1. Resolve user input `TimeZone` with the `SystemTimeZone`.
67
+ /// 2. Get the `SystemNanoseconds`
68
+ ///
69
+ /// For an example implementation see [`Self::zoneddatetime_iso`]
70
+ pub fn zoneddatetime_iso_with_system_values (
71
+ epoch_nanos : EpochNanoseconds ,
72
+ timezone : TimeZone ,
57
73
) -> TemporalResult < ZonedDateTime > {
58
- let timezone = timezone. unwrap_or ( TimeZone :: IanaIdentifier (
59
- system_hooks. get_system_time_zone ( ) ?,
60
- ) ) ;
61
- let instant = Self :: instant_with_hooks ( system_hooks) ?;
74
+ let instant = Self :: instant_with_epoch_nanoseconds ( epoch_nanos) ;
62
75
Ok ( ZonedDateTime :: new_unchecked (
63
76
instant,
64
77
Calendar :: default ( ) ,
@@ -71,79 +84,104 @@ impl Now {
71
84
impl Now {
72
85
/// Returns the current instant
73
86
pub fn instant ( ) -> TemporalResult < Instant > {
74
- Self :: instant_with_hooks ( & DefaultSystemHooks )
87
+ let system_nanos = crate :: sys:: get_system_nanoseconds ( ) ?;
88
+ let epoch_nanos = EpochNanoseconds :: try_from ( system_nanos) ?;
89
+ Ok ( Self :: instant_with_epoch_nanoseconds ( epoch_nanos) )
75
90
}
76
91
77
92
/// Returns the current time zone.
78
93
pub fn time_zone_identifier ( ) -> TemporalResult < String > {
79
- Self :: system_time_zone_identifier_with_hooks ( & DefaultSystemHooks )
94
+ crate :: sys :: get_system_timezone ( )
80
95
}
81
96
}
82
97
83
98
impl Now {
84
99
/// Returns the current system time as a `PlainDateTime` with an ISO8601 calendar.
85
100
///
86
- /// The time zone used to calculate the `PlainDateTime` will be set to either the
87
- /// `TimeZone` if a value is provided, or according to the system timezone if no
88
- /// value is provided.
89
- pub fn plain_datetime_iso_with_hooks_and_provider (
90
- timezone : Option < TimeZone > ,
91
- system_hooks : & impl SystemHooks ,
101
+ /// ## Order of operations
102
+ ///
103
+ /// The order of operations for this method requires the `GetSystemTimeZone` call
104
+ /// to occur prior to calling system time and resolving the `EpochNanoseconds`
105
+ /// value.
106
+ ///
107
+ /// A correct implementation will follow the following steps:
108
+ ///
109
+ /// 1. Resolve user input `TimeZone` with the `SystemTimeZone`.
110
+ /// 2. Get the `SystemNanoseconds`
111
+ ///
112
+ /// For an example implementation see [`Self::plain_date_time_iso`]
113
+ pub fn plain_datetime_iso_with_provider (
114
+ epoch_nanos : EpochNanoseconds ,
115
+ timezone : TimeZone ,
92
116
provider : & impl TimeZoneProvider ,
93
117
) -> TemporalResult < PlainDateTime > {
94
- let iso = Self :: system_datetime_with_hooks_and_provider ( timezone , system_hooks , provider) ?;
118
+ let iso = Self :: system_datetime_with_provider ( epoch_nanos , timezone , provider) ?;
95
119
Ok ( PlainDateTime :: new_unchecked ( iso, Calendar :: default ( ) ) )
96
120
}
97
121
98
122
/// Returns the current system time as a `PlainDate` with an ISO8601 calendar.
99
123
///
100
- /// The time zone used to calculate the `PlainDate` will be set to either the
101
- /// `TimeZone` if a value is provided, or according to the system timezone if no
102
- /// value is provided.
103
- pub fn plain_date_iso_with_hooks_and_provider (
104
- timezone : Option < TimeZone > ,
105
- system_hooks : & impl SystemHooks ,
124
+ /// ## Order of operations
125
+ ///
126
+ /// The order of operations for this method requires the `GetSystemTimeZone` call
127
+ /// to occur prior to calling system time and resolving the `EpochNanoseconds`
128
+ /// value.
129
+ ///
130
+ /// A correct implementation will follow the following steps:
131
+ ///
132
+ /// 1. Resolve user input `TimeZone` with the `SystemTimeZone`.
133
+ /// 2. Get the `SystemNanoseconds`
134
+ ///
135
+ /// For an example implementation see [`Self::plain_date_iso`]
136
+ pub fn plain_date_iso_with_provider (
137
+ epoch_nanos : EpochNanoseconds ,
138
+ timezone : TimeZone ,
106
139
provider : & impl TimeZoneProvider ,
107
140
) -> TemporalResult < PlainDate > {
108
- let iso = Self :: system_datetime_with_hooks_and_provider ( timezone , system_hooks , provider) ?;
141
+ let iso = Self :: system_datetime_with_provider ( epoch_nanos , timezone , provider) ?;
109
142
Ok ( PlainDate :: new_unchecked ( iso. date , Calendar :: default ( ) ) )
110
143
}
111
144
112
145
/// Returns the current system time as a `PlainTime` according to an ISO8601 calendar.
113
146
///
114
- /// The time zone used to calculate the `PlainTime` will be set to either the
115
- /// `TimeZone` if a value is provided, or according to the system timezone if no
116
- /// value is provided.
117
- pub fn plain_time_iso_with_hooks_and_provider (
118
- timezone : Option < TimeZone > ,
119
- system_hooks : & impl SystemHooks ,
147
+ /// ## Order of operations
148
+ ///
149
+ /// The order of operations for this method requires the `GetSystemTimeZone` call
150
+ /// to occur prior to calling system time and resolving the `EpochNanoseconds`
151
+ /// value.
152
+ ///
153
+ /// A correct implementation will follow the following steps:
154
+ ///
155
+ /// 1. Resolve user input `TimeZone` with the `SystemTimeZone`.
156
+ /// 2. Get the `SystemNanoseconds`
157
+ ///
158
+ /// For an example implementation see [`Self::plain_time_iso`]
159
+ pub fn plain_time_iso_with_provider (
160
+ epoch_nanos : EpochNanoseconds ,
161
+ timezone : TimeZone ,
120
162
provider : & impl TimeZoneProvider ,
121
163
) -> TemporalResult < PlainTime > {
122
- let iso = Self :: system_datetime_with_hooks_and_provider ( timezone , system_hooks , provider) ?;
164
+ let iso = Self :: system_datetime_with_provider ( epoch_nanos , timezone , provider) ?;
123
165
Ok ( PlainTime :: new_unchecked ( iso. time ) )
124
166
}
125
167
}
126
168
127
169
#[ cfg( all( feature = "tzdb" , feature = "sys" ) ) ]
128
170
#[ cfg( test) ]
129
171
mod tests {
172
+ use crate :: builtins:: core:: Now ;
130
173
use std:: thread;
131
174
use std:: time:: Duration as StdDuration ;
132
175
133
- use crate :: builtins:: core:: Now ;
134
- use crate :: { options:: DifferenceSettings , sys:: DefaultSystemHooks , tzdb:: FsTzdbProvider } ;
176
+ use crate :: options:: DifferenceSettings ;
135
177
136
178
#[ test]
137
179
fn now_datetime_test ( ) {
138
- let provider = & FsTzdbProvider :: default ( ) ;
139
- let system_hooks = DefaultSystemHooks ;
140
180
let sleep = 2 ;
141
181
142
- let before =
143
- Now :: plain_datetime_iso_with_hooks_and_provider ( None , & system_hooks, provider) . unwrap ( ) ;
182
+ let before = Now :: plain_datetime_iso ( None ) . unwrap ( ) ;
144
183
thread:: sleep ( StdDuration :: from_secs ( sleep) ) ;
145
- let after =
146
- Now :: plain_datetime_iso_with_hooks_and_provider ( None , & system_hooks, provider) . unwrap ( ) ;
184
+ let after = Now :: plain_datetime_iso ( None ) . unwrap ( ) ;
147
185
148
186
let diff = after. since ( & before, DifferenceSettings :: default ( ) ) . unwrap ( ) ;
149
187
0 commit comments