From b77ed50184e5a326a3cc3b5569d3da178f819dac Mon Sep 17 00:00:00 2001 From: Cliff Dyer Date: Mon, 18 Dec 2023 23:50:40 -0500 Subject: [PATCH] Add direct constructors for `OffsetDateTime`. (#641) --- tests/offset_date_time.rs | 89 ++++++++++++++++++------------------ time/src/offset_date_time.rs | 33 +++++++++++++ 2 files changed, 77 insertions(+), 45 deletions(-) diff --git a/tests/offset_date_time.rs b/tests/offset_date_time.rs index 86db74a89..a9593d7d3 100644 --- a/tests/offset_date_time.rs +++ b/tests/offset_date_time.rs @@ -5,6 +5,23 @@ use time::ext::{NumericalDuration, NumericalStdDuration}; use time::macros::{date, datetime, offset, time}; use time::{Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Result, Weekday}; +#[test] +fn new_utc() { + let dt = OffsetDateTime::new_utc(date!(2023 - 12 - 18), time!(10:13:44.250 AM)); + assert_eq!(dt.year(), 2023); + assert_eq!(dt.millisecond(), 250); + assert_eq!(dt.offset(), offset!(UTC)); +} + +#[test] +fn new_in_offset() { + let dt = + OffsetDateTime::new_in_offset(date!(2023 - 12 - 18), time!(10:13:44.250 AM), offset!(-4)); + assert_eq!(dt.year(), 2023); + assert_eq!(dt.millisecond(), 250); + assert_eq!(dt.offset().whole_hours(), -4); +} + #[test] fn now_utc() { assert!(OffsetDateTime::now_utc().year() >= 2019); @@ -433,16 +450,12 @@ fn replace_year() -> Result<()> { datetime!(2022 - 02 - 18 12:00 +01).replace_year(2019), Ok(datetime!(2019 - 02 - 18 12:00 +01)) ); - 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 - 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 + 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 + 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 Ok(()) } @@ -452,11 +465,9 @@ fn replace_month() -> Result<()> { datetime!(2022 - 02 - 18 12:00 +01).replace_month(Month::January), Ok(datetime!(2022 - 01 - 18 12:00 +01)) ); - assert!( - datetime!(2022 - 01 - 30 12:00 +01) - .replace_month(Month::February) - .is_err() - ); // 30 isn't a valid day in February + assert!(datetime!(2022 - 01 - 30 12:00 +01) + .replace_month(Month::February) + .is_err()); // 30 isn't a valid day in February Ok(()) } @@ -477,11 +488,9 @@ fn replace_hour() -> Result<()> { datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_hour(7), Ok(datetime!(2022 - 02 - 18 07:02:03.004_005_006 +01)) ); - assert!( - datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01) - .replace_hour(24) - .is_err() - ); // 24 isn't a valid hour + assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01) + .replace_hour(24) + .is_err()); // 24 isn't a valid hour Ok(()) } @@ -491,11 +500,9 @@ fn replace_minute() -> Result<()> { datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_minute(7), Ok(datetime!(2022 - 02 - 18 01:07:03.004_005_006 +01)) ); - assert!( - datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01) - .replace_minute(60) - .is_err() - ); // 60 isn't a valid minute + assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01) + .replace_minute(60) + .is_err()); // 60 isn't a valid minute Ok(()) } @@ -505,11 +512,9 @@ fn replace_second() -> Result<()> { datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_second(7), Ok(datetime!(2022 - 02 - 18 01:02:07.004_005_006 +01)) ); - assert!( - datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01) - .replace_second(60) - .is_err() - ); // 60 isn't a valid second + assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01) + .replace_second(60) + .is_err()); // 60 isn't a valid second Ok(()) } @@ -519,11 +524,9 @@ fn replace_millisecond() -> Result<()> { datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_millisecond(7), Ok(datetime!(2022 - 02 - 18 01:02:03.007 +01)) ); - 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 + 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 Ok(()) } @@ -533,11 +536,9 @@ fn replace_microsecond() -> Result<()> { datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_microsecond(7_008), Ok(datetime!(2022 - 02 - 18 01:02:03.007_008 +01)) ); - 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 + 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 Ok(()) } @@ -547,11 +548,9 @@ fn replace_nanosecond() -> Result<()> { datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_nanosecond(7_008_009), Ok(datetime!(2022 - 02 - 18 01:02:03.007_008_009 +01)) ); - 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 + 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 Ok(()) } diff --git a/time/src/offset_date_time.rs b/time/src/offset_date_time.rs index 79d91a61b..dcdd2b2f9 100644 --- a/time/src/offset_date_time.rs +++ b/time/src/offset_date_time.rs @@ -71,6 +71,39 @@ impl OffsetDateTime { } // endregion now + /// Create a new `OffsetDateTime` with the given [`Date`], [`Time`], and [`UtcOffset`]. + /// + /// ``` + /// # use time::{Date, Month, OffsetDateTime, Time, UtcOffset}; + /// # use time_macros::datetime; + /// let dt = OffsetDateTime::new_in_offset( + /// Date::from_calendar_date(2024, Month::January, 1)?, + /// Time::from_hms_nano(12, 59, 59, 500_000_000)?, + /// UtcOffset::from_hms(-5, 0, 0)?, + /// ); + /// assert_eq!(dt, datetime!(2024-01-01 12:59:59.5 -5)); + /// # Ok::<_, time::error::Error>(()) + /// ``` + pub const fn new_in_offset(date: Date, time: Time, offset: UtcOffset) -> Self { + PrimitiveDateTime::new(date, time).assume_offset(offset) + } + + /// Create a new `OffsetDateTime` with the given [`Date`] and [`Time`] in the UTC timezone. + /// + /// ``` + /// # use time::{Date, Month, OffsetDateTime, Time}; + /// # use time_macros::datetime; + /// let dt = OffsetDateTime::new_utc( + /// Date::from_calendar_date(2024, Month::January, 1)?, + /// Time::from_hms_nano(12, 59, 59, 500_000_000)?, + /// ); + /// assert_eq!(dt, datetime!(2024-01-01 12:59:59.5 UTC)); + /// # Ok::<_, time::error::Error>(()) + /// ``` + pub const fn new_utc(date: Date, time: Time) -> Self { + PrimitiveDateTime::new(date, time).assume_utc() + } + /// Convert the `OffsetDateTime` from the current [`UtcOffset`] to the provided [`UtcOffset`]. /// /// ```rust