Skip to content

Commit

Permalink
Add DateTime::to_timezone and FromOffset trait
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Apr 12, 2024
1 parent f8cecbe commit 2944362
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 5 deletions.
22 changes: 19 additions & 3 deletions src/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::format::{write_rfc2822, write_rfc3339, DelayedFormat, SecondsFormat};
use crate::naive::{Days, IsoWeek, NaiveDate, NaiveDateTime, NaiveTime};
#[cfg(feature = "clock")]
use crate::offset::Local;
use crate::offset::{FixedOffset, LocalResult, Offset, TimeZone, Utc};
use crate::offset::{FixedOffset, FromOffset, LocalResult, Offset, TimeZone, Utc};
#[allow(deprecated)]
use crate::Date;
use crate::{expect, try_opt};
Expand Down Expand Up @@ -405,14 +405,30 @@ impl<Tz: TimeZone> DateTime<Tz> {
}

/// Changes the associated time zone.
/// The returned `DateTime` references the same instant of time from the perspective of the
/// provided time zone.
///
/// The returned `DateTime` references the same instant of time in UTC but with the offset of
/// the target time zone.
#[inline]
#[must_use]
pub fn with_timezone<Tz2: TimeZone>(&self, tz: &Tz2) -> DateTime<Tz2> {
tz.from_utc_datetime(&self.datetime)
}

/// Changes the associated `TimeZone` type.
///
/// The returned `DateTime` references the same instant of time in UTC but with another
/// [`TimeZone`] type. A best effort is made to convert the value of the associated [`Offset`]
/// type to the `Offset` type of the target `TimeZone`.
#[inline]
#[must_use]
pub fn to_timezone<Tz2: TimeZone>(&self) -> DateTime<Tz2>
where
<Tz2 as TimeZone>::Offset: FromOffset<<Tz as TimeZone>::Offset>,
{
let new_offset = <Tz2 as TimeZone>::Offset::from_offset(self.offset());
DateTime { datetime: self.datetime, offset: new_offset }
}

Check warning on line 430 in src/datetime/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/datetime/mod.rs#L424-L430

Added lines #L424 - L430 were not covered by tests

/// Fix the offset from UTC to its current value, dropping the associated timezone information.
/// This it useful for converting a generic `DateTime<Tz: Timezone>` to `DateTime<FixedOffset>`.
#[inline]
Expand Down
11 changes: 10 additions & 1 deletion src/offset/fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use core::str::FromStr;
#[cfg(any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"))]
use rkyv::{Archive, Deserialize, Serialize};

use super::{MappedLocalTime, Offset, TimeZone};
use super::{FromOffset, MappedLocalTime, Offset, TimeZone};
use crate::format::{scan, ParseError, OUT_OF_RANGE};
use crate::naive::{NaiveDate, NaiveDateTime};

Expand Down Expand Up @@ -152,6 +152,15 @@ impl Offset for FixedOffset {
}
}

impl<Off> FromOffset<Off> for FixedOffset
where
Off: Offset
{
fn from_offset(offset: &Off) -> Self {
offset.fix()
}

Check warning on line 161 in src/offset/fixed.rs

View check run for this annotation

Codecov / codecov/patch

src/offset/fixed.rs#L159-L161

Added lines #L159 - L161 were not covered by tests
}

impl fmt::Debug for FixedOffset {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let offset = self.local_minus_utc;
Expand Down
6 changes: 6 additions & 0 deletions src/offset/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,12 @@ pub trait TimeZone: Sized + Clone {
}
}

/// Trait to create one `Offset` type from another `Offset` type.
pub trait FromOffset<Off> {
/// Converts to this type from the input type.
fn from_offset(offset: &Off) -> Self;
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
11 changes: 10 additions & 1 deletion src/offset/utc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"))]
use rkyv::{Archive, Deserialize, Serialize};

use super::{FixedOffset, MappedLocalTime, Offset, TimeZone};
use super::{FixedOffset, FromOffset, MappedLocalTime, Offset, TimeZone};
use crate::naive::{NaiveDate, NaiveDateTime};
#[cfg(feature = "now")]
#[allow(deprecated)]
Expand Down Expand Up @@ -139,6 +139,15 @@ impl Offset for Utc {
}
}

impl<Off> FromOffset<Off> for Utc
where
Off: Offset
{
fn from_offset(_offset: &Off) -> Self {
Utc
}

Check warning on line 148 in src/offset/utc.rs

View check run for this annotation

Codecov / codecov/patch

src/offset/utc.rs#L146-L148

Added lines #L146 - L148 were not covered by tests
}

impl fmt::Debug for Utc {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Z")
Expand Down

0 comments on commit 2944362

Please sign in to comment.