Skip to content

Commit

Permalink
Added checked_to_timezone
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuri6037 committed Mar 1, 2024
1 parent 088f34d commit 2be1f26
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "time-tz"
version = "3.0.0-rc.1.0.0"
version = "3.0.0-rc.2.0.0"
edition = "2021"
authors = ["Yuri Edward <[email protected]>"]
description = "Implementation of tz database (IANA) for the time Rust crate."
Expand Down
6 changes: 6 additions & 0 deletions src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,15 @@ impl OffsetDateTimeExt for OffsetDateTime {

impl<T: TimeZone> ToTimezone<&T> for OffsetDateTime {
type Out = OffsetDateTime;
type CheckedOut = Option<OffsetDateTime>;

fn to_timezone(&self, tz: &T) -> OffsetDateTime {
let offset = tz.get_offset_utc(self);
self.to_offset(offset.to_utc())
}

fn checked_to_timezone(&self, tz: &T) -> Self::CheckedOut {
let offset = tz.get_offset_utc(self);
self.checked_to_offset(offset.to_utc())
}
}
13 changes: 12 additions & 1 deletion src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,24 @@ pub trait ToTimezone<T> {
/// The output type.
type Out;

/// The output type for checked_to_timezone.
type CheckedOut;

/// Converts self to a different timezone.
///
/// # Panics
///
/// This function panics if the date_time + computed_offset would be out of range according to
/// [OffsetDateTime](OffsetDateTime).
fn to_timezone(&self, tz: T) -> Self::Out;

/// Converts self to a different timezone.
fn checked_to_timezone(&self, tz: T) -> Self::CheckedOut;
}

/// This trait represents a particular timezone offset.
pub trait Offset {
/// Converts this timezone offset to a [UtcOffset](time::UtcOffset).
/// Converts this timezone offset to a [UtcOffset](UtcOffset).
fn to_utc(&self) -> UtcOffset;

/// Returns the name of this offset.
Expand Down
8 changes: 8 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,4 +221,12 @@ mod tests {
.unwrap_first().offset_date_time()
);
}

#[test]
fn errors() {
let datetime = datetime!(2024-03-31 02:30:00).assume_timezone(timezones::db::europe::BUDAPEST);
assert!(datetime.is_none());
let datetime = datetime!(2024-03-31 02:29:00).assume_timezone(timezones::db::europe::BUDAPEST);
assert!(datetime.is_none());
}
}
34 changes: 34 additions & 0 deletions src/posix_tz/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ pub enum Error {
/// We've exceeded the maximum date supported by time-rs.
#[error("value of Date too large")]
DateTooLarge,

/// The resulting date time would be out of range.
#[error("resulting date time would be out of range")]
OutOfRange
}

/// A POSIX "timezone" offset.
Expand Down Expand Up @@ -154,11 +158,36 @@ impl<'a> PosixTz<'a> {
///
/// Returns an [Error](crate::posix_tz::Error) if the date_time cannot be represented in this
/// "timezone".
///
/// # Panics
///
/// This function panics if the date_time + computed_offset would be out of range according to
/// [OffsetDateTime](OffsetDateTime).
pub fn convert(&self, date_time: &OffsetDateTime) -> Result<OffsetDateTime, Error> {
let offset = self.get_offset(date_time)?;
Ok(date_time.to_offset(offset.to_utc()))
}

/// Convert the given date_time to this "timezone".
///
/// # Arguments
///
/// * `date_time`: the date time to convert.
///
/// returns: Result<OffsetDateTime, Error>
///
/// # Errors
///
/// Returns an [Error](crate::posix_tz::Error) if the date_time cannot be represented in this
/// "timezone".
pub fn checked_convert(&self, date_time: &OffsetDateTime) -> Result<OffsetDateTime, Error> {
let offset = self.get_offset(date_time)?;
match date_time.checked_to_offset(offset.to_utc()) {
Some(v) => Ok(v),
None => Err(Error::OutOfRange)
}
}

/// Calculates the offset to add to the given date_time to convert it to this "timezone".
///
/// # Arguments
Expand Down Expand Up @@ -207,8 +236,13 @@ impl<'a> PosixTz<'a> {

impl<'a> ToTimezone<&PosixTz<'a>> for OffsetDateTime {
type Out = Result<OffsetDateTime, Error>;
type CheckedOut = Self::Out;

fn to_timezone(&self, tz: &PosixTz) -> Self::Out {
tz.convert(self)
}

fn checked_to_timezone(&self, tz: &PosixTz<'a>) -> Self::CheckedOut {
tz.checked_convert(self)
}
}
6 changes: 6 additions & 0 deletions src/timezones.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,15 @@ pub fn get_by_name(name: &str) -> Option<&'static Tz> {

impl ToTimezone<&str> for OffsetDateTime {
type Out = Option<OffsetDateTime>;
type CheckedOut = Self::Out;

fn to_timezone(&self, tz: &str) -> Self::Out {
let tz = get_by_name(tz)?;
Some(self.to_timezone(tz))
}

fn checked_to_timezone(&self, tz: &str) -> Self::CheckedOut {
let tz = get_by_name(tz)?;
self.checked_to_timezone(tz)
}
}

0 comments on commit 2be1f26

Please sign in to comment.