Last active
January 27, 2022 01:27
-
-
Save x7c1/7c93283ceee41acc18eeebabc2896c85 to your computer and use it in GitHub Desktop.
Create type-safe TimeZone by wrapping chrono_tz::Tz.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use chrono::{ | |
| DateTime, Datelike, FixedOffset, LocalResult, NaiveDate, NaiveDateTime, TimeZone, Timelike, | |
| }; | |
| use chrono_tz::{Asia, Tz}; | |
| use std::marker::PhantomData; | |
| #[test] | |
| fn typed_time_zone() { | |
| let x1: DateTime<FixedOffset> = DateTime::parse_from_rfc3339("2001-01-01T01:02:03Z").unwrap(); | |
| let x2: DateTime<Jst> = x1.with_timezone(&TypedTz::new()); | |
| assert_eq!(x2.to_rfc3339(), "2001-01-01T10:02:03+09:00"); | |
| let x3: DateTime<Pst> = x1.with_timezone(&TypedTz::new()); | |
| assert_eq!(x3.to_rfc3339(), "2000-12-31T17:02:03-08:00"); | |
| } | |
| type Jst = TypedTz<JstZone>; | |
| #[derive(Clone)] | |
| struct JstZone; | |
| impl HazTz for JstZone { | |
| fn tz() -> Tz { | |
| Asia::Tokyo | |
| } | |
| } | |
| type Pst = TypedTz<PstZone>; | |
| #[derive(Clone)] | |
| struct PstZone; | |
| impl HazTz for PstZone { | |
| fn tz() -> Tz { | |
| US::Pacific | |
| } | |
| } | |
| trait HazTz { | |
| fn tz() -> Tz; | |
| } | |
| #[derive(Clone)] | |
| struct TypedTz<A: HazTz>(Tz, PhantomData<A>); | |
| impl<A: HazTz> TypedTz<A> { | |
| pub fn new() -> Self { | |
| Self(A::tz(), PhantomData) | |
| } | |
| } | |
| impl<A> TimeZone for TypedTz<A> | |
| where | |
| A: Clone, | |
| A: HazTz, | |
| { | |
| type Offset = <Tz as TimeZone>::Offset; | |
| fn from_offset(offset: &Self::Offset) -> Self { | |
| let tz = <Tz as TimeZone>::from_offset(offset); | |
| Self(tz, PhantomData) | |
| } | |
| fn offset_from_local_date(&self, local: &NaiveDate) -> LocalResult<Self::Offset> { | |
| self.0.offset_from_local_date(local) | |
| } | |
| fn offset_from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<Self::Offset> { | |
| self.0.offset_from_local_datetime(local) | |
| } | |
| fn offset_from_utc_date(&self, utc: &NaiveDate) -> Self::Offset { | |
| self.0.offset_from_utc_date(utc) | |
| } | |
| fn offset_from_utc_datetime(&self, utc: &NaiveDateTime) -> Self::Offset { | |
| self.0.offset_from_utc_datetime(utc) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment