Skip to content

Instantly share code, notes, and snippets.

@x7c1
Last active January 27, 2022 01:27
Show Gist options
  • Select an option

  • Save x7c1/7c93283ceee41acc18eeebabc2896c85 to your computer and use it in GitHub Desktop.

Select an option

Save x7c1/7c93283ceee41acc18eeebabc2896c85 to your computer and use it in GitHub Desktop.
Create type-safe TimeZone by wrapping chrono_tz::Tz.
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