1 | //! The [`OffsetDateTime`] struct and its associated `impl`s. |
2 | |
3 | #[cfg (feature = "std" )] |
4 | use core::cmp::Ordering; |
5 | #[cfg (feature = "std" )] |
6 | use core::convert::From; |
7 | use core::fmt; |
8 | use core::hash::Hash; |
9 | use core::ops::{Add, AddAssign, Sub, SubAssign}; |
10 | use core::time::Duration as StdDuration; |
11 | #[cfg (feature = "formatting" )] |
12 | use std::io; |
13 | #[cfg (feature = "std" )] |
14 | use std::time::SystemTime; |
15 | |
16 | use crate::date_time::offset_kind; |
17 | #[cfg (feature = "formatting" )] |
18 | use crate::formatting::Formattable; |
19 | #[cfg (feature = "parsing" )] |
20 | use crate::parsing::Parsable; |
21 | use crate::{error, Date, DateTime, Duration, Month, PrimitiveDateTime, Time, UtcOffset, Weekday}; |
22 | |
23 | /// The actual type doing all the work. |
24 | type Inner = DateTime<offset_kind::Fixed>; |
25 | |
26 | /// A [`PrimitiveDateTime`] with a [`UtcOffset`]. |
27 | /// |
28 | /// All comparisons are performed using the UTC time. |
29 | #[derive (Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
30 | pub struct OffsetDateTime(pub(crate) Inner); |
31 | |
32 | impl OffsetDateTime { |
33 | /// Midnight, 1 January, 1970 (UTC). |
34 | /// |
35 | /// ```rust |
36 | /// # use time::OffsetDateTime; |
37 | /// # use time_macros::datetime; |
38 | /// assert_eq!(OffsetDateTime::UNIX_EPOCH, datetime!(1970-01-01 0:00 UTC),); |
39 | /// ``` |
40 | pub const UNIX_EPOCH: Self = Self(Inner::UNIX_EPOCH); |
41 | |
42 | // region: now |
43 | /// Create a new `OffsetDateTime` with the current date and time in UTC. |
44 | /// |
45 | /// ```rust |
46 | /// # use time::OffsetDateTime; |
47 | /// # use time_macros::offset; |
48 | /// assert!(OffsetDateTime::now_utc().year() >= 2019); |
49 | /// assert_eq!(OffsetDateTime::now_utc().offset(), offset!(UTC)); |
50 | /// ``` |
51 | #[cfg (feature = "std" )] |
52 | pub fn now_utc() -> Self { |
53 | Self(Inner::now_utc()) |
54 | } |
55 | |
56 | /// Attempt to create a new `OffsetDateTime` with the current date and time in the local offset. |
57 | /// If the offset cannot be determined, an error is returned. |
58 | /// |
59 | /// ```rust |
60 | /// # use time::OffsetDateTime; |
61 | /// # if false { |
62 | /// assert!(OffsetDateTime::now_local().is_ok()); |
63 | /// # } |
64 | /// ``` |
65 | #[cfg (feature = "local-offset" )] |
66 | pub fn now_local() -> Result<Self, error::IndeterminateOffset> { |
67 | Inner::now_local().map(Self) |
68 | } |
69 | // endregion now |
70 | |
71 | /// Convert the `OffsetDateTime` from the current [`UtcOffset`] to the provided [`UtcOffset`]. |
72 | /// |
73 | /// ```rust |
74 | /// # use time_macros::{datetime, offset}; |
75 | /// assert_eq!( |
76 | /// datetime!(2000-01-01 0:00 UTC) |
77 | /// .to_offset(offset!(-1)) |
78 | /// .year(), |
79 | /// 1999, |
80 | /// ); |
81 | /// |
82 | /// // Let's see what time Sydney's new year's celebration is in New York and Los Angeles. |
83 | /// |
84 | /// // Construct midnight on new year's in Sydney. |
85 | /// let sydney = datetime!(2000-01-01 0:00 +11); |
86 | /// let new_york = sydney.to_offset(offset!(-5)); |
87 | /// let los_angeles = sydney.to_offset(offset!(-8)); |
88 | /// assert_eq!(sydney.hour(), 0); |
89 | /// assert_eq!(new_york.hour(), 8); |
90 | /// assert_eq!(los_angeles.hour(), 5); |
91 | /// ``` |
92 | /// |
93 | /// # Panics |
94 | /// |
95 | /// This method panics if the local date-time in the new offset is outside the supported range. |
96 | pub const fn to_offset(self, offset: UtcOffset) -> Self { |
97 | Self(self.0.to_offset(offset)) |
98 | } |
99 | |
100 | /// Convert the `OffsetDateTime` from the current [`UtcOffset`] to the provided [`UtcOffset`], |
101 | /// returning `None` if the date-time in the resulting offset is invalid. |
102 | /// |
103 | /// ```rust |
104 | /// # use time::PrimitiveDateTime; |
105 | /// # use time_macros::{datetime, offset}; |
106 | /// assert_eq!( |
107 | /// datetime!(2000-01-01 0:00 UTC) |
108 | /// .checked_to_offset(offset!(-1)) |
109 | /// .unwrap() |
110 | /// .year(), |
111 | /// 1999, |
112 | /// ); |
113 | /// assert_eq!( |
114 | /// PrimitiveDateTime::MAX |
115 | /// .assume_utc() |
116 | /// .checked_to_offset(offset!(+1)), |
117 | /// None, |
118 | /// ); |
119 | /// ``` |
120 | pub const fn checked_to_offset(self, offset: UtcOffset) -> Option<Self> { |
121 | Some(Self(const_try_opt!(self.0.checked_to_offset(offset)))) |
122 | } |
123 | |
124 | // region: constructors |
125 | /// Create an `OffsetDateTime` from the provided Unix timestamp. Calling `.offset()` on the |
126 | /// resulting value is guaranteed to return UTC. |
127 | /// |
128 | /// ```rust |
129 | /// # use time::OffsetDateTime; |
130 | /// # use time_macros::datetime; |
131 | /// assert_eq!( |
132 | /// OffsetDateTime::from_unix_timestamp(0), |
133 | /// Ok(OffsetDateTime::UNIX_EPOCH), |
134 | /// ); |
135 | /// assert_eq!( |
136 | /// OffsetDateTime::from_unix_timestamp(1_546_300_800), |
137 | /// Ok(datetime!(2019-01-01 0:00 UTC)), |
138 | /// ); |
139 | /// ``` |
140 | /// |
141 | /// If you have a timestamp-nanosecond pair, you can use something along the lines of the |
142 | /// following: |
143 | /// |
144 | /// ```rust |
145 | /// # use time::{Duration, OffsetDateTime, ext::NumericalDuration}; |
146 | /// let (timestamp, nanos) = (1, 500_000_000); |
147 | /// assert_eq!( |
148 | /// OffsetDateTime::from_unix_timestamp(timestamp)? + Duration::nanoseconds(nanos), |
149 | /// OffsetDateTime::UNIX_EPOCH + 1.5.seconds() |
150 | /// ); |
151 | /// # Ok::<_, time::Error>(()) |
152 | /// ``` |
153 | pub const fn from_unix_timestamp(timestamp: i64) -> Result<Self, error::ComponentRange> { |
154 | Ok(Self(const_try!(Inner::from_unix_timestamp(timestamp)))) |
155 | } |
156 | |
157 | /// Construct an `OffsetDateTime` from the provided Unix timestamp (in nanoseconds). Calling |
158 | /// `.offset()` on the resulting value is guaranteed to return UTC. |
159 | /// |
160 | /// ```rust |
161 | /// # use time::OffsetDateTime; |
162 | /// # use time_macros::datetime; |
163 | /// assert_eq!( |
164 | /// OffsetDateTime::from_unix_timestamp_nanos(0), |
165 | /// Ok(OffsetDateTime::UNIX_EPOCH), |
166 | /// ); |
167 | /// assert_eq!( |
168 | /// OffsetDateTime::from_unix_timestamp_nanos(1_546_300_800_000_000_000), |
169 | /// Ok(datetime!(2019-01-01 0:00 UTC)), |
170 | /// ); |
171 | /// ``` |
172 | pub const fn from_unix_timestamp_nanos(timestamp: i128) -> Result<Self, error::ComponentRange> { |
173 | Ok(Self(const_try!(Inner::from_unix_timestamp_nanos( |
174 | timestamp |
175 | )))) |
176 | } |
177 | // endregion constructors |
178 | |
179 | // region: getters |
180 | /// Get the [`UtcOffset`]. |
181 | /// |
182 | /// ```rust |
183 | /// # use time_macros::{datetime, offset}; |
184 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).offset(), offset!(UTC)); |
185 | /// assert_eq!(datetime!(2019-01-01 0:00 +1).offset(), offset!(+1)); |
186 | /// ``` |
187 | pub const fn offset(self) -> UtcOffset { |
188 | self.0.offset() |
189 | } |
190 | |
191 | /// Get the [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time). |
192 | /// |
193 | /// ```rust |
194 | /// # use time_macros::datetime; |
195 | /// assert_eq!(datetime!(1970-01-01 0:00 UTC).unix_timestamp(), 0); |
196 | /// assert_eq!(datetime!(1970-01-01 0:00 -1).unix_timestamp(), 3_600); |
197 | /// ``` |
198 | pub const fn unix_timestamp(self) -> i64 { |
199 | self.0.unix_timestamp() |
200 | } |
201 | |
202 | /// Get the Unix timestamp in nanoseconds. |
203 | /// |
204 | /// ```rust |
205 | /// use time_macros::datetime; |
206 | /// assert_eq!(datetime!(1970-01-01 0:00 UTC).unix_timestamp_nanos(), 0); |
207 | /// assert_eq!( |
208 | /// datetime!(1970-01-01 0:00 -1).unix_timestamp_nanos(), |
209 | /// 3_600_000_000_000, |
210 | /// ); |
211 | /// ``` |
212 | pub const fn unix_timestamp_nanos(self) -> i128 { |
213 | self.0.unix_timestamp_nanos() |
214 | } |
215 | |
216 | /// Get the [`Date`] in the stored offset. |
217 | /// |
218 | /// ```rust |
219 | /// # use time_macros::{date, datetime, offset}; |
220 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).date(), date!(2019-01-01)); |
221 | /// assert_eq!( |
222 | /// datetime!(2019-01-01 0:00 UTC) |
223 | /// .to_offset(offset!(-1)) |
224 | /// .date(), |
225 | /// date!(2018-12-31), |
226 | /// ); |
227 | /// ``` |
228 | pub const fn date(self) -> Date { |
229 | self.0.date() |
230 | } |
231 | |
232 | /// Get the [`Time`] in the stored offset. |
233 | /// |
234 | /// ```rust |
235 | /// # use time_macros::{datetime, offset, time}; |
236 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).time(), time!(0:00)); |
237 | /// assert_eq!( |
238 | /// datetime!(2019-01-01 0:00 UTC) |
239 | /// .to_offset(offset!(-1)) |
240 | /// .time(), |
241 | /// time!(23:00) |
242 | /// ); |
243 | /// ``` |
244 | pub const fn time(self) -> Time { |
245 | self.0.time() |
246 | } |
247 | |
248 | // region: date getters |
249 | /// Get the year of the date in the stored offset. |
250 | /// |
251 | /// ```rust |
252 | /// # use time_macros::{datetime, offset}; |
253 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).year(), 2019); |
254 | /// assert_eq!( |
255 | /// datetime!(2019-12-31 23:00 UTC) |
256 | /// .to_offset(offset!(+1)) |
257 | /// .year(), |
258 | /// 2020, |
259 | /// ); |
260 | /// assert_eq!(datetime!(2020-01-01 0:00 UTC).year(), 2020); |
261 | /// ``` |
262 | pub const fn year(self) -> i32 { |
263 | self.0.year() |
264 | } |
265 | |
266 | /// Get the month of the date in the stored offset. |
267 | /// |
268 | /// ```rust |
269 | /// # use time::Month; |
270 | /// # use time_macros::{datetime, offset}; |
271 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).month(), Month::January); |
272 | /// assert_eq!( |
273 | /// datetime!(2019-12-31 23:00 UTC) |
274 | /// .to_offset(offset!(+1)) |
275 | /// .month(), |
276 | /// Month::January, |
277 | /// ); |
278 | /// ``` |
279 | pub const fn month(self) -> Month { |
280 | self.0.month() |
281 | } |
282 | |
283 | /// Get the day of the date in the stored offset. |
284 | /// |
285 | /// The returned value will always be in the range `1..=31`. |
286 | /// |
287 | /// ```rust |
288 | /// # use time_macros::{datetime, offset}; |
289 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).day(), 1); |
290 | /// assert_eq!( |
291 | /// datetime!(2019-12-31 23:00 UTC) |
292 | /// .to_offset(offset!(+1)) |
293 | /// .day(), |
294 | /// 1, |
295 | /// ); |
296 | /// ``` |
297 | pub const fn day(self) -> u8 { |
298 | self.0.day() |
299 | } |
300 | |
301 | /// Get the day of the year of the date in the stored offset. |
302 | /// |
303 | /// The returned value will always be in the range `1..=366`. |
304 | /// |
305 | /// ```rust |
306 | /// # use time_macros::{datetime, offset}; |
307 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).ordinal(), 1); |
308 | /// assert_eq!( |
309 | /// datetime!(2019-12-31 23:00 UTC) |
310 | /// .to_offset(offset!(+1)) |
311 | /// .ordinal(), |
312 | /// 1, |
313 | /// ); |
314 | /// ``` |
315 | pub const fn ordinal(self) -> u16 { |
316 | self.0.ordinal() |
317 | } |
318 | |
319 | /// Get the ISO week number of the date in the stored offset. |
320 | /// |
321 | /// The returned value will always be in the range `1..=53`. |
322 | /// |
323 | /// ```rust |
324 | /// # use time_macros::datetime; |
325 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).iso_week(), 1); |
326 | /// assert_eq!(datetime!(2020-01-01 0:00 UTC).iso_week(), 1); |
327 | /// assert_eq!(datetime!(2020-12-31 0:00 UTC).iso_week(), 53); |
328 | /// assert_eq!(datetime!(2021-01-01 0:00 UTC).iso_week(), 53); |
329 | /// ``` |
330 | pub const fn iso_week(self) -> u8 { |
331 | self.0.iso_week() |
332 | } |
333 | |
334 | /// Get the week number where week 1 begins on the first Sunday. |
335 | /// |
336 | /// The returned value will always be in the range `0..=53`. |
337 | /// |
338 | /// ```rust |
339 | /// # use time_macros::datetime; |
340 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).sunday_based_week(), 0); |
341 | /// assert_eq!(datetime!(2020-01-01 0:00 UTC).sunday_based_week(), 0); |
342 | /// assert_eq!(datetime!(2020-12-31 0:00 UTC).sunday_based_week(), 52); |
343 | /// assert_eq!(datetime!(2021-01-01 0:00 UTC).sunday_based_week(), 0); |
344 | /// ``` |
345 | pub const fn sunday_based_week(self) -> u8 { |
346 | self.0.sunday_based_week() |
347 | } |
348 | |
349 | /// Get the week number where week 1 begins on the first Monday. |
350 | /// |
351 | /// The returned value will always be in the range `0..=53`. |
352 | /// |
353 | /// ```rust |
354 | /// # use time_macros::datetime; |
355 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).monday_based_week(), 0); |
356 | /// assert_eq!(datetime!(2020-01-01 0:00 UTC).monday_based_week(), 0); |
357 | /// assert_eq!(datetime!(2020-12-31 0:00 UTC).monday_based_week(), 52); |
358 | /// assert_eq!(datetime!(2021-01-01 0:00 UTC).monday_based_week(), 0); |
359 | /// ``` |
360 | pub const fn monday_based_week(self) -> u8 { |
361 | self.0.monday_based_week() |
362 | } |
363 | |
364 | /// Get the year, month, and day. |
365 | /// |
366 | /// ```rust |
367 | /// # use time::Month; |
368 | /// # use time_macros::datetime; |
369 | /// assert_eq!( |
370 | /// datetime!(2019-01-01 0:00 UTC).to_calendar_date(), |
371 | /// (2019, Month::January, 1) |
372 | /// ); |
373 | /// ``` |
374 | pub const fn to_calendar_date(self) -> (i32, Month, u8) { |
375 | self.0.to_calendar_date() |
376 | } |
377 | |
378 | /// Get the year and ordinal day number. |
379 | /// |
380 | /// ```rust |
381 | /// # use time_macros::datetime; |
382 | /// assert_eq!( |
383 | /// datetime!(2019-01-01 0:00 UTC).to_ordinal_date(), |
384 | /// (2019, 1) |
385 | /// ); |
386 | /// ``` |
387 | pub const fn to_ordinal_date(self) -> (i32, u16) { |
388 | self.0.to_ordinal_date() |
389 | } |
390 | |
391 | /// Get the ISO 8601 year, week number, and weekday. |
392 | /// |
393 | /// ```rust |
394 | /// # use time::Weekday::*; |
395 | /// # use time_macros::datetime; |
396 | /// assert_eq!( |
397 | /// datetime!(2019-01-01 0:00 UTC).to_iso_week_date(), |
398 | /// (2019, 1, Tuesday) |
399 | /// ); |
400 | /// assert_eq!( |
401 | /// datetime!(2019-10-04 0:00 UTC).to_iso_week_date(), |
402 | /// (2019, 40, Friday) |
403 | /// ); |
404 | /// assert_eq!( |
405 | /// datetime!(2020-01-01 0:00 UTC).to_iso_week_date(), |
406 | /// (2020, 1, Wednesday) |
407 | /// ); |
408 | /// assert_eq!( |
409 | /// datetime!(2020-12-31 0:00 UTC).to_iso_week_date(), |
410 | /// (2020, 53, Thursday) |
411 | /// ); |
412 | /// assert_eq!( |
413 | /// datetime!(2021-01-01 0:00 UTC).to_iso_week_date(), |
414 | /// (2020, 53, Friday) |
415 | /// ); |
416 | /// ``` |
417 | pub const fn to_iso_week_date(self) -> (i32, u8, Weekday) { |
418 | self.0.to_iso_week_date() |
419 | } |
420 | |
421 | /// Get the weekday of the date in the stored offset. |
422 | /// |
423 | /// ```rust |
424 | /// # use time::Weekday::*; |
425 | /// # use time_macros::datetime; |
426 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).weekday(), Tuesday); |
427 | /// assert_eq!(datetime!(2019-02-01 0:00 UTC).weekday(), Friday); |
428 | /// assert_eq!(datetime!(2019-03-01 0:00 UTC).weekday(), Friday); |
429 | /// ``` |
430 | pub const fn weekday(self) -> Weekday { |
431 | self.0.weekday() |
432 | } |
433 | |
434 | /// Get the Julian day for the date. The time is not taken into account for this calculation. |
435 | /// |
436 | /// The algorithm to perform this conversion is derived from one provided by Peter Baum; it is |
437 | /// freely available [here](https://www.researchgate.net/publication/316558298_Date_Algorithms). |
438 | /// |
439 | /// ```rust |
440 | /// # use time_macros::datetime; |
441 | /// assert_eq!(datetime!(-4713-11-24 0:00 UTC).to_julian_day(), 0); |
442 | /// assert_eq!(datetime!(2000-01-01 0:00 UTC).to_julian_day(), 2_451_545); |
443 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).to_julian_day(), 2_458_485); |
444 | /// assert_eq!(datetime!(2019-12-31 0:00 UTC).to_julian_day(), 2_458_849); |
445 | /// ``` |
446 | pub const fn to_julian_day(self) -> i32 { |
447 | self.0.to_julian_day() |
448 | } |
449 | // endregion date getters |
450 | |
451 | // region: time getters |
452 | /// Get the clock hour, minute, and second. |
453 | /// |
454 | /// ```rust |
455 | /// # use time_macros::datetime; |
456 | /// assert_eq!(datetime!(2020-01-01 0:00:00 UTC).to_hms(), (0, 0, 0)); |
457 | /// assert_eq!(datetime!(2020-01-01 23:59:59 UTC).to_hms(), (23, 59, 59)); |
458 | /// ``` |
459 | pub const fn to_hms(self) -> (u8, u8, u8) { |
460 | self.0.as_hms() |
461 | } |
462 | |
463 | /// Get the clock hour, minute, second, and millisecond. |
464 | /// |
465 | /// ```rust |
466 | /// # use time_macros::datetime; |
467 | /// assert_eq!( |
468 | /// datetime!(2020-01-01 0:00:00 UTC).to_hms_milli(), |
469 | /// (0, 0, 0, 0) |
470 | /// ); |
471 | /// assert_eq!( |
472 | /// datetime!(2020-01-01 23:59:59.999 UTC).to_hms_milli(), |
473 | /// (23, 59, 59, 999) |
474 | /// ); |
475 | /// ``` |
476 | pub const fn to_hms_milli(self) -> (u8, u8, u8, u16) { |
477 | self.0.as_hms_milli() |
478 | } |
479 | |
480 | /// Get the clock hour, minute, second, and microsecond. |
481 | /// |
482 | /// ```rust |
483 | /// # use time_macros::datetime; |
484 | /// assert_eq!( |
485 | /// datetime!(2020-01-01 0:00:00 UTC).to_hms_micro(), |
486 | /// (0, 0, 0, 0) |
487 | /// ); |
488 | /// assert_eq!( |
489 | /// datetime!(2020-01-01 23:59:59.999_999 UTC).to_hms_micro(), |
490 | /// (23, 59, 59, 999_999) |
491 | /// ); |
492 | /// ``` |
493 | pub const fn to_hms_micro(self) -> (u8, u8, u8, u32) { |
494 | self.0.as_hms_micro() |
495 | } |
496 | |
497 | /// Get the clock hour, minute, second, and nanosecond. |
498 | /// |
499 | /// ```rust |
500 | /// # use time_macros::datetime; |
501 | /// assert_eq!( |
502 | /// datetime!(2020-01-01 0:00:00 UTC).to_hms_nano(), |
503 | /// (0, 0, 0, 0) |
504 | /// ); |
505 | /// assert_eq!( |
506 | /// datetime!(2020-01-01 23:59:59.999_999_999 UTC).to_hms_nano(), |
507 | /// (23, 59, 59, 999_999_999) |
508 | /// ); |
509 | /// ``` |
510 | pub const fn to_hms_nano(self) -> (u8, u8, u8, u32) { |
511 | self.0.as_hms_nano() |
512 | } |
513 | |
514 | /// Get the clock hour in the stored offset. |
515 | /// |
516 | /// The returned value will always be in the range `0..24`. |
517 | /// |
518 | /// ```rust |
519 | /// # use time_macros::{datetime, offset}; |
520 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).hour(), 0); |
521 | /// assert_eq!( |
522 | /// datetime!(2019-01-01 23:59:59 UTC) |
523 | /// .to_offset(offset!(-2)) |
524 | /// .hour(), |
525 | /// 21, |
526 | /// ); |
527 | /// ``` |
528 | pub const fn hour(self) -> u8 { |
529 | self.0.hour() |
530 | } |
531 | |
532 | /// Get the minute within the hour in the stored offset. |
533 | /// |
534 | /// The returned value will always be in the range `0..60`. |
535 | /// |
536 | /// ```rust |
537 | /// # use time_macros::{datetime, offset}; |
538 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).minute(), 0); |
539 | /// assert_eq!( |
540 | /// datetime!(2019-01-01 23:59:59 UTC) |
541 | /// .to_offset(offset!(+0:30)) |
542 | /// .minute(), |
543 | /// 29, |
544 | /// ); |
545 | /// ``` |
546 | pub const fn minute(self) -> u8 { |
547 | self.0.minute() |
548 | } |
549 | |
550 | /// Get the second within the minute in the stored offset. |
551 | /// |
552 | /// The returned value will always be in the range `0..60`. |
553 | /// |
554 | /// ```rust |
555 | /// # use time_macros::{datetime, offset}; |
556 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).second(), 0); |
557 | /// assert_eq!( |
558 | /// datetime!(2019-01-01 23:59:59 UTC) |
559 | /// .to_offset(offset!(+0:00:30)) |
560 | /// .second(), |
561 | /// 29, |
562 | /// ); |
563 | /// ``` |
564 | pub const fn second(self) -> u8 { |
565 | self.0.second() |
566 | } |
567 | |
568 | // Because a `UtcOffset` is limited in resolution to one second, any subsecond value will not |
569 | // change when adjusting for the offset. |
570 | |
571 | /// Get the milliseconds within the second in the stored offset. |
572 | /// |
573 | /// The returned value will always be in the range `0..1_000`. |
574 | /// |
575 | /// ```rust |
576 | /// # use time_macros::datetime; |
577 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).millisecond(), 0); |
578 | /// assert_eq!(datetime!(2019-01-01 23:59:59.999 UTC).millisecond(), 999); |
579 | /// ``` |
580 | pub const fn millisecond(self) -> u16 { |
581 | self.0.millisecond() |
582 | } |
583 | |
584 | /// Get the microseconds within the second in the stored offset. |
585 | /// |
586 | /// The returned value will always be in the range `0..1_000_000`. |
587 | /// |
588 | /// ```rust |
589 | /// # use time_macros::datetime; |
590 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).microsecond(), 0); |
591 | /// assert_eq!( |
592 | /// datetime!(2019-01-01 23:59:59.999_999 UTC).microsecond(), |
593 | /// 999_999, |
594 | /// ); |
595 | /// ``` |
596 | pub const fn microsecond(self) -> u32 { |
597 | self.0.microsecond() |
598 | } |
599 | |
600 | /// Get the nanoseconds within the second in the stored offset. |
601 | /// |
602 | /// The returned value will always be in the range `0..1_000_000_000`. |
603 | /// |
604 | /// ```rust |
605 | /// # use time_macros::datetime; |
606 | /// assert_eq!(datetime!(2019-01-01 0:00 UTC).nanosecond(), 0); |
607 | /// assert_eq!( |
608 | /// datetime!(2019-01-01 23:59:59.999_999_999 UTC).nanosecond(), |
609 | /// 999_999_999, |
610 | /// ); |
611 | /// ``` |
612 | pub const fn nanosecond(self) -> u32 { |
613 | self.0.nanosecond() |
614 | } |
615 | // endregion time getters |
616 | // endregion getters |
617 | |
618 | // region: checked arithmetic |
619 | /// Computes `self + duration`, returning `None` if an overflow occurred. |
620 | /// |
621 | /// ``` |
622 | /// # use time::{Date, ext::NumericalDuration}; |
623 | /// # use time_macros::{datetime, offset}; |
624 | /// let datetime = Date::MIN.midnight().assume_offset(offset!(+10)); |
625 | /// assert_eq!(datetime.checked_add((-2).days()), None); |
626 | /// |
627 | /// let datetime = Date::MAX.midnight().assume_offset(offset!(+10)); |
628 | /// assert_eq!(datetime.checked_add(2.days()), None); |
629 | /// |
630 | /// assert_eq!( |
631 | /// datetime!(2019 - 11 - 25 15:30 +10).checked_add(27.hours()), |
632 | /// Some(datetime!(2019 - 11 - 26 18:30 +10)) |
633 | /// ); |
634 | /// ``` |
635 | pub const fn checked_add(self, duration: Duration) -> Option<Self> { |
636 | Some(Self(const_try_opt!(self.0.checked_add(duration)))) |
637 | } |
638 | |
639 | /// Computes `self - duration`, returning `None` if an overflow occurred. |
640 | /// |
641 | /// ``` |
642 | /// # use time::{Date, ext::NumericalDuration}; |
643 | /// # use time_macros::{datetime, offset}; |
644 | /// let datetime = Date::MIN.midnight().assume_offset(offset!(+10)); |
645 | /// assert_eq!(datetime.checked_sub(2.days()), None); |
646 | /// |
647 | /// let datetime = Date::MAX.midnight().assume_offset(offset!(+10)); |
648 | /// assert_eq!(datetime.checked_sub((-2).days()), None); |
649 | /// |
650 | /// assert_eq!( |
651 | /// datetime!(2019 - 11 - 25 15:30 +10).checked_sub(27.hours()), |
652 | /// Some(datetime!(2019 - 11 - 24 12:30 +10)) |
653 | /// ); |
654 | /// ``` |
655 | pub const fn checked_sub(self, duration: Duration) -> Option<Self> { |
656 | Some(Self(const_try_opt!(self.0.checked_sub(duration)))) |
657 | } |
658 | // endregion: checked arithmetic |
659 | |
660 | // region: saturating arithmetic |
661 | /// Computes `self + duration`, saturating value on overflow. |
662 | /// |
663 | /// ``` |
664 | /// # use time::ext::NumericalDuration; |
665 | /// # use time_macros::datetime; |
666 | /// assert_eq!( |
667 | #[cfg_attr ( |
668 | feature = "large-dates" , |
669 | doc = " datetime!(-999999-01-01 0:00 +10).saturating_add((-2).days())," |
670 | )] |
671 | #[cfg_attr (feature = "large-dates" , doc = " datetime!(-999999-01-01 0:00 +10)" )] |
672 | #[cfg_attr ( |
673 | not(feature = "large-dates" ), |
674 | doc = " datetime!(-9999-01-01 0:00 +10).saturating_add((-2).days())," |
675 | )] |
676 | #[cfg_attr ( |
677 | not(feature = "large-dates" ), |
678 | doc = " datetime!(-9999-01-01 0:00 +10)" |
679 | )] |
680 | /// ); |
681 | /// |
682 | /// assert_eq!( |
683 | #[cfg_attr ( |
684 | feature = "large-dates" , |
685 | doc = " datetime!(+999999-12-31 23:59:59.999_999_999 +10).saturating_add(2.days())," |
686 | )] |
687 | #[cfg_attr ( |
688 | feature = "large-dates" , |
689 | doc = " datetime!(+999999-12-31 23:59:59.999_999_999 +10)" |
690 | )] |
691 | #[cfg_attr ( |
692 | not(feature = "large-dates" ), |
693 | doc = " datetime!(+9999-12-31 23:59:59.999_999_999 +10).saturating_add(2.days())," |
694 | )] |
695 | #[cfg_attr ( |
696 | not(feature = "large-dates" ), |
697 | doc = " datetime!(+9999-12-31 23:59:59.999_999_999 +10)" |
698 | )] |
699 | /// ); |
700 | /// |
701 | /// assert_eq!( |
702 | /// datetime!(2019 - 11 - 25 15:30 +10).saturating_add(27.hours()), |
703 | /// datetime!(2019 - 11 - 26 18:30 +10) |
704 | /// ); |
705 | /// ``` |
706 | pub const fn saturating_add(self, duration: Duration) -> Self { |
707 | Self(self.0.saturating_add(duration)) |
708 | } |
709 | |
710 | /// Computes `self - duration`, saturating value on overflow. |
711 | /// |
712 | /// ``` |
713 | /// # use time::ext::NumericalDuration; |
714 | /// # use time_macros::datetime; |
715 | /// assert_eq!( |
716 | #[cfg_attr ( |
717 | feature = "large-dates" , |
718 | doc = " datetime!(-999999-01-01 0:00 +10).saturating_sub(2.days())," |
719 | )] |
720 | #[cfg_attr (feature = "large-dates" , doc = " datetime!(-999999-01-01 0:00 +10)" )] |
721 | #[cfg_attr ( |
722 | not(feature = "large-dates" ), |
723 | doc = " datetime!(-9999-01-01 0:00 +10).saturating_sub(2.days())," |
724 | )] |
725 | #[cfg_attr ( |
726 | not(feature = "large-dates" ), |
727 | doc = " datetime!(-9999-01-01 0:00 +10)" |
728 | )] |
729 | /// ); |
730 | /// |
731 | /// assert_eq!( |
732 | #[cfg_attr ( |
733 | feature = "large-dates" , |
734 | doc = " datetime!(+999999-12-31 23:59:59.999_999_999 +10).saturating_sub((-2).days())," |
735 | )] |
736 | #[cfg_attr ( |
737 | feature = "large-dates" , |
738 | doc = " datetime!(+999999-12-31 23:59:59.999_999_999 +10)" |
739 | )] |
740 | #[cfg_attr ( |
741 | not(feature = "large-dates" ), |
742 | doc = " datetime!(+9999-12-31 23:59:59.999_999_999 +10).saturating_sub((-2).days())," |
743 | )] |
744 | #[cfg_attr ( |
745 | not(feature = "large-dates" ), |
746 | doc = " datetime!(+9999-12-31 23:59:59.999_999_999 +10)" |
747 | )] |
748 | /// ); |
749 | /// |
750 | /// assert_eq!( |
751 | /// datetime!(2019 - 11 - 25 15:30 +10).saturating_sub(27.hours()), |
752 | /// datetime!(2019 - 11 - 24 12:30 +10) |
753 | /// ); |
754 | /// ``` |
755 | pub const fn saturating_sub(self, duration: Duration) -> Self { |
756 | Self(self.0.saturating_sub(duration)) |
757 | } |
758 | // endregion: saturating arithmetic |
759 | } |
760 | |
761 | // region: replacement |
762 | /// Methods that replace part of the `OffsetDateTime`. |
763 | impl OffsetDateTime { |
764 | /// Replace the time, which is assumed to be in the stored offset. The date and offset |
765 | /// components are unchanged. |
766 | /// |
767 | /// ```rust |
768 | /// # use time_macros::{datetime, time}; |
769 | /// assert_eq!( |
770 | /// datetime!(2020-01-01 5:00 UTC).replace_time(time!(12:00)), |
771 | /// datetime!(2020-01-01 12:00 UTC) |
772 | /// ); |
773 | /// assert_eq!( |
774 | /// datetime!(2020-01-01 12:00 -5).replace_time(time!(7:00)), |
775 | /// datetime!(2020-01-01 7:00 -5) |
776 | /// ); |
777 | /// assert_eq!( |
778 | /// datetime!(2020-01-01 0:00 +1).replace_time(time!(12:00)), |
779 | /// datetime!(2020-01-01 12:00 +1) |
780 | /// ); |
781 | /// ``` |
782 | #[must_use = "This method does not mutate the original `OffsetDateTime`." ] |
783 | pub const fn replace_time(self, time: Time) -> Self { |
784 | Self(self.0.replace_time(time)) |
785 | } |
786 | |
787 | /// Replace the date, which is assumed to be in the stored offset. The time and offset |
788 | /// components are unchanged. |
789 | /// |
790 | /// ```rust |
791 | /// # use time_macros::{datetime, date}; |
792 | /// assert_eq!( |
793 | /// datetime!(2020-01-01 12:00 UTC).replace_date(date!(2020-01-30)), |
794 | /// datetime!(2020-01-30 12:00 UTC) |
795 | /// ); |
796 | /// assert_eq!( |
797 | /// datetime!(2020-01-01 0:00 +1).replace_date(date!(2020-01-30)), |
798 | /// datetime!(2020-01-30 0:00 +1) |
799 | /// ); |
800 | /// ``` |
801 | #[must_use = "This method does not mutate the original `OffsetDateTime`." ] |
802 | pub const fn replace_date(self, date: Date) -> Self { |
803 | Self(self.0.replace_date(date)) |
804 | } |
805 | |
806 | /// Replace the date and time, which are assumed to be in the stored offset. The offset |
807 | /// component remains unchanged. |
808 | /// |
809 | /// ```rust |
810 | /// # use time_macros::datetime; |
811 | /// assert_eq!( |
812 | /// datetime!(2020-01-01 12:00 UTC).replace_date_time(datetime!(2020-01-30 16:00)), |
813 | /// datetime!(2020-01-30 16:00 UTC) |
814 | /// ); |
815 | /// assert_eq!( |
816 | /// datetime!(2020-01-01 12:00 +1).replace_date_time(datetime!(2020-01-30 0:00)), |
817 | /// datetime!(2020-01-30 0:00 +1) |
818 | /// ); |
819 | /// ``` |
820 | #[must_use = "This method does not mutate the original `OffsetDateTime`." ] |
821 | pub const fn replace_date_time(self, date_time: PrimitiveDateTime) -> Self { |
822 | Self(self.0.replace_date_time(date_time.0)) |
823 | } |
824 | |
825 | /// Replace the offset. The date and time components remain unchanged. |
826 | /// |
827 | /// ```rust |
828 | /// # use time_macros::{datetime, offset}; |
829 | /// assert_eq!( |
830 | /// datetime!(2020-01-01 0:00 UTC).replace_offset(offset!(-5)), |
831 | /// datetime!(2020-01-01 0:00 -5) |
832 | /// ); |
833 | /// ``` |
834 | #[must_use = "This method does not mutate the original `OffsetDateTime`." ] |
835 | pub const fn replace_offset(self, offset: UtcOffset) -> Self { |
836 | Self(self.0.replace_offset(offset)) |
837 | } |
838 | |
839 | /// Replace the year. The month and day will be unchanged. |
840 | /// |
841 | /// ```rust |
842 | /// # use time_macros::datetime; |
843 | /// assert_eq!( |
844 | /// datetime!(2022 - 02 - 18 12:00 +01).replace_year(2019), |
845 | /// Ok(datetime!(2019 - 02 - 18 12:00 +01)) |
846 | /// ); |
847 | /// assert!(datetime!(2022 - 02 - 18 12:00 +01).replace_year(-1_000_000_000).is_err()); // -1_000_000_000 isn't a valid year |
848 | /// assert!(datetime!(2022 - 02 - 18 12:00 +01).replace_year(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid year |
849 | /// ``` |
850 | pub const fn replace_year(self, year: i32) -> Result<Self, error::ComponentRange> { |
851 | Ok(Self(const_try!(self.0.replace_year(year)))) |
852 | } |
853 | |
854 | /// Replace the month of the year. |
855 | /// |
856 | /// ```rust |
857 | /// # use time_macros::datetime; |
858 | /// # use time::Month; |
859 | /// assert_eq!( |
860 | /// datetime!(2022 - 02 - 18 12:00 +01).replace_month(Month::January), |
861 | /// Ok(datetime!(2022 - 01 - 18 12:00 +01)) |
862 | /// ); |
863 | /// assert!(datetime!(2022 - 01 - 30 12:00 +01).replace_month(Month::February).is_err()); // 30 isn't a valid day in February |
864 | /// ``` |
865 | pub const fn replace_month(self, month: Month) -> Result<Self, error::ComponentRange> { |
866 | Ok(Self(const_try!(self.0.replace_month(month)))) |
867 | } |
868 | |
869 | /// Replace the day of the month. |
870 | /// |
871 | /// ```rust |
872 | /// # use time_macros::datetime; |
873 | /// assert_eq!( |
874 | /// datetime!(2022 - 02 - 18 12:00 +01).replace_day(1), |
875 | /// Ok(datetime!(2022 - 02 - 01 12:00 +01)) |
876 | /// ); |
877 | /// assert!(datetime!(2022 - 02 - 18 12:00 +01).replace_day(0).is_err()); // 00 isn't a valid day |
878 | /// assert!(datetime!(2022 - 02 - 18 12:00 +01).replace_day(30).is_err()); // 30 isn't a valid day in February |
879 | /// ``` |
880 | pub const fn replace_day(self, day: u8) -> Result<Self, error::ComponentRange> { |
881 | Ok(Self(const_try!(self.0.replace_day(day)))) |
882 | } |
883 | |
884 | /// Replace the clock hour. |
885 | /// |
886 | /// ```rust |
887 | /// # use time_macros::datetime; |
888 | /// assert_eq!( |
889 | /// datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_hour(7), |
890 | /// Ok(datetime!(2022 - 02 - 18 07:02:03.004_005_006 +01)) |
891 | /// ); |
892 | /// assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_hour(24).is_err()); // 24 isn't a valid hour |
893 | /// ``` |
894 | pub const fn replace_hour(self, hour: u8) -> Result<Self, error::ComponentRange> { |
895 | Ok(Self(const_try!(self.0.replace_hour(hour)))) |
896 | } |
897 | |
898 | /// Replace the minutes within the hour. |
899 | /// |
900 | /// ```rust |
901 | /// # use time_macros::datetime; |
902 | /// assert_eq!( |
903 | /// datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_minute(7), |
904 | /// Ok(datetime!(2022 - 02 - 18 01:07:03.004_005_006 +01)) |
905 | /// ); |
906 | /// assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_minute(60).is_err()); // 60 isn't a valid minute |
907 | /// ``` |
908 | pub const fn replace_minute(self, minute: u8) -> Result<Self, error::ComponentRange> { |
909 | Ok(Self(const_try!(self.0.replace_minute(minute)))) |
910 | } |
911 | |
912 | /// Replace the seconds within the minute. |
913 | /// |
914 | /// ```rust |
915 | /// # use time_macros::datetime; |
916 | /// assert_eq!( |
917 | /// datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_second(7), |
918 | /// Ok(datetime!(2022 - 02 - 18 01:02:07.004_005_006 +01)) |
919 | /// ); |
920 | /// assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_second(60).is_err()); // 60 isn't a valid second |
921 | /// ``` |
922 | pub const fn replace_second(self, second: u8) -> Result<Self, error::ComponentRange> { |
923 | Ok(Self(const_try!(self.0.replace_second(second)))) |
924 | } |
925 | |
926 | /// Replace the milliseconds within the second. |
927 | /// |
928 | /// ```rust |
929 | /// # use time_macros::datetime; |
930 | /// assert_eq!( |
931 | /// datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_millisecond(7), |
932 | /// Ok(datetime!(2022 - 02 - 18 01:02:03.007 +01)) |
933 | /// ); |
934 | /// assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_millisecond(1_000).is_err()); // 1_000 isn't a valid millisecond |
935 | /// ``` |
936 | pub const fn replace_millisecond( |
937 | self, |
938 | millisecond: u16, |
939 | ) -> Result<Self, error::ComponentRange> { |
940 | Ok(Self(const_try!(self.0.replace_millisecond(millisecond)))) |
941 | } |
942 | |
943 | /// Replace the microseconds within the second. |
944 | /// |
945 | /// ```rust |
946 | /// # use time_macros::datetime; |
947 | /// assert_eq!( |
948 | /// datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_microsecond(7_008), |
949 | /// Ok(datetime!(2022 - 02 - 18 01:02:03.007_008 +01)) |
950 | /// ); |
951 | /// assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_microsecond(1_000_000).is_err()); // 1_000_000 isn't a valid microsecond |
952 | /// ``` |
953 | pub const fn replace_microsecond( |
954 | self, |
955 | microsecond: u32, |
956 | ) -> Result<Self, error::ComponentRange> { |
957 | Ok(Self(const_try!(self.0.replace_microsecond(microsecond)))) |
958 | } |
959 | |
960 | /// Replace the nanoseconds within the second. |
961 | /// |
962 | /// ```rust |
963 | /// # use time_macros::datetime; |
964 | /// assert_eq!( |
965 | /// datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_nanosecond(7_008_009), |
966 | /// Ok(datetime!(2022 - 02 - 18 01:02:03.007_008_009 +01)) |
967 | /// ); |
968 | /// assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_nanosecond(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid nanosecond |
969 | /// ``` |
970 | pub const fn replace_nanosecond(self, nanosecond: u32) -> Result<Self, error::ComponentRange> { |
971 | Ok(Self(const_try!(self.0.replace_nanosecond(nanosecond)))) |
972 | } |
973 | } |
974 | // endregion replacement |
975 | |
976 | // region: formatting & parsing |
977 | #[cfg (feature = "formatting" )] |
978 | impl OffsetDateTime { |
979 | /// Format the `OffsetDateTime` using the provided [format |
980 | /// description](crate::format_description). |
981 | pub fn format_into( |
982 | self, |
983 | output: &mut impl io::Write, |
984 | format: &(impl Formattable + ?Sized), |
985 | ) -> Result<usize, error::Format> { |
986 | self.0.format_into(output, format) |
987 | } |
988 | |
989 | /// Format the `OffsetDateTime` using the provided [format |
990 | /// description](crate::format_description). |
991 | /// |
992 | /// ```rust |
993 | /// # use time::format_description; |
994 | /// # use time_macros::datetime; |
995 | /// let format = format_description::parse( |
996 | /// "[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour \ |
997 | /// sign:mandatory]:[offset_minute]:[offset_second]" , |
998 | /// )?; |
999 | /// assert_eq!( |
1000 | /// datetime!(2020-01-02 03:04:05 +06:07:08).format(&format)?, |
1001 | /// "2020-01-02 03:04:05 +06:07:08" |
1002 | /// ); |
1003 | /// # Ok::<_, time::Error>(()) |
1004 | /// ``` |
1005 | pub fn format(self, format: &(impl Formattable + ?Sized)) -> Result<String, error::Format> { |
1006 | self.0.format(format) |
1007 | } |
1008 | } |
1009 | |
1010 | #[cfg (feature = "parsing" )] |
1011 | impl OffsetDateTime { |
1012 | /// Parse an `OffsetDateTime` from the input using the provided [format |
1013 | /// description](crate::format_description). |
1014 | /// |
1015 | /// ```rust |
1016 | /// # use time::OffsetDateTime; |
1017 | /// # use time_macros::{datetime, format_description}; |
1018 | /// let format = format_description!( |
1019 | /// "[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour \ |
1020 | /// sign:mandatory]:[offset_minute]:[offset_second]" |
1021 | /// ); |
1022 | /// assert_eq!( |
1023 | /// OffsetDateTime::parse("2020-01-02 03:04:05 +06:07:08", &format)?, |
1024 | /// datetime!(2020-01-02 03:04:05 +06:07:08) |
1025 | /// ); |
1026 | /// # Ok::<_, time::Error>(()) |
1027 | /// ``` |
1028 | pub fn parse( |
1029 | input: &str, |
1030 | description: &(impl Parsable + ?Sized), |
1031 | ) -> Result<Self, error::Parse> { |
1032 | Inner::parse(input, description).map(Self) |
1033 | } |
1034 | } |
1035 | |
1036 | impl fmt::Display for OffsetDateTime { |
1037 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1038 | self.0.fmt(f) |
1039 | } |
1040 | } |
1041 | |
1042 | impl fmt::Debug for OffsetDateTime { |
1043 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1044 | fmt::Display::fmt(self, f) |
1045 | } |
1046 | } |
1047 | // endregion formatting & parsing |
1048 | |
1049 | // region: trait impls |
1050 | impl Add<Duration> for OffsetDateTime { |
1051 | type Output = Self; |
1052 | |
1053 | fn add(self, rhs: Duration) -> Self::Output { |
1054 | Self(self.0.add(rhs)) |
1055 | } |
1056 | } |
1057 | |
1058 | impl Add<StdDuration> for OffsetDateTime { |
1059 | type Output = Self; |
1060 | |
1061 | fn add(self, rhs: StdDuration) -> Self::Output { |
1062 | Self(self.0.add(rhs)) |
1063 | } |
1064 | } |
1065 | |
1066 | impl AddAssign<Duration> for OffsetDateTime { |
1067 | fn add_assign(&mut self, rhs: Duration) { |
1068 | self.0.add_assign(rhs); |
1069 | } |
1070 | } |
1071 | |
1072 | impl AddAssign<StdDuration> for OffsetDateTime { |
1073 | fn add_assign(&mut self, rhs: StdDuration) { |
1074 | self.0.add_assign(rhs); |
1075 | } |
1076 | } |
1077 | |
1078 | impl Sub<Duration> for OffsetDateTime { |
1079 | type Output = Self; |
1080 | |
1081 | fn sub(self, rhs: Duration) -> Self::Output { |
1082 | Self(self.0.sub(rhs)) |
1083 | } |
1084 | } |
1085 | |
1086 | impl Sub<StdDuration> for OffsetDateTime { |
1087 | type Output = Self; |
1088 | |
1089 | fn sub(self, rhs: StdDuration) -> Self::Output { |
1090 | Self(self.0.sub(rhs)) |
1091 | } |
1092 | } |
1093 | |
1094 | impl SubAssign<Duration> for OffsetDateTime { |
1095 | fn sub_assign(&mut self, rhs: Duration) { |
1096 | self.0.sub_assign(rhs); |
1097 | } |
1098 | } |
1099 | |
1100 | impl SubAssign<StdDuration> for OffsetDateTime { |
1101 | fn sub_assign(&mut self, rhs: StdDuration) { |
1102 | self.0.sub_assign(rhs); |
1103 | } |
1104 | } |
1105 | |
1106 | impl Sub for OffsetDateTime { |
1107 | type Output = Duration; |
1108 | |
1109 | fn sub(self, rhs: Self) -> Self::Output { |
1110 | self.0.sub(rhs.0) |
1111 | } |
1112 | } |
1113 | |
1114 | #[cfg (feature = "std" )] |
1115 | impl Sub<SystemTime> for OffsetDateTime { |
1116 | type Output = Duration; |
1117 | |
1118 | fn sub(self, rhs: SystemTime) -> Self::Output { |
1119 | self.0.sub(rhs) |
1120 | } |
1121 | } |
1122 | |
1123 | #[cfg (feature = "std" )] |
1124 | impl Sub<OffsetDateTime> for SystemTime { |
1125 | type Output = Duration; |
1126 | |
1127 | fn sub(self, rhs: OffsetDateTime) -> Self::Output { |
1128 | self.sub(rhs.0) |
1129 | } |
1130 | } |
1131 | |
1132 | #[cfg (feature = "std" )] |
1133 | impl PartialEq<SystemTime> for OffsetDateTime { |
1134 | fn eq(&self, rhs: &SystemTime) -> bool { |
1135 | self.0.eq(rhs) |
1136 | } |
1137 | } |
1138 | |
1139 | #[cfg (feature = "std" )] |
1140 | impl PartialEq<OffsetDateTime> for SystemTime { |
1141 | fn eq(&self, rhs: &OffsetDateTime) -> bool { |
1142 | self.eq(&rhs.0) |
1143 | } |
1144 | } |
1145 | |
1146 | #[cfg (feature = "std" )] |
1147 | impl PartialOrd<SystemTime> for OffsetDateTime { |
1148 | fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering> { |
1149 | self.0.partial_cmp(other) |
1150 | } |
1151 | } |
1152 | |
1153 | #[cfg (feature = "std" )] |
1154 | impl PartialOrd<OffsetDateTime> for SystemTime { |
1155 | fn partial_cmp(&self, other: &OffsetDateTime) -> Option<Ordering> { |
1156 | self.partial_cmp(&other.0) |
1157 | } |
1158 | } |
1159 | |
1160 | #[cfg (feature = "std" )] |
1161 | impl From<SystemTime> for OffsetDateTime { |
1162 | fn from(system_time: SystemTime) -> Self { |
1163 | Self(Inner::from(system_time)) |
1164 | } |
1165 | } |
1166 | |
1167 | #[cfg (feature = "std" )] |
1168 | impl From<OffsetDateTime> for SystemTime { |
1169 | fn from(datetime: OffsetDateTime) -> Self { |
1170 | datetime.0.into() |
1171 | } |
1172 | } |
1173 | |
1174 | #[cfg (all( |
1175 | target_family = "wasm" , |
1176 | not(any(target_os = "emscripten" , target_os = "wasi" )), |
1177 | feature = "wasm-bindgen" |
1178 | ))] |
1179 | impl From<js_sys::Date> for OffsetDateTime { |
1180 | fn from(js_date: js_sys::Date) -> Self { |
1181 | Self(Inner::from(js_date)) |
1182 | } |
1183 | } |
1184 | |
1185 | #[cfg (all( |
1186 | target_family = "wasm" , |
1187 | not(any(target_os = "emscripten" , target_os = "wasi" )), |
1188 | feature = "wasm-bindgen" |
1189 | ))] |
1190 | impl From<OffsetDateTime> for js_sys::Date { |
1191 | fn from(datetime: OffsetDateTime) -> Self { |
1192 | datetime.0.into() |
1193 | } |
1194 | } |
1195 | |
1196 | // endregion trait impls |
1197 | |