1

I want to return the local time at a timezone using chrono and chrono-tz. NaiveDate and NaiveDateTime can be converted to DateTime<Tz>, but I can't convert DateTime<FixedOffset> to DateTime<Tz>.

// tz is Asia/Tokyo
// 2004-02-13                    => 2004-02-13T00:00:00+09:00
// 2004-02-13T04:00:00           => 2004-02-13T04:00:00+09:00
// 2004-02-13T04:00:00           => 2004-02-13T04:00:00+09:00
// 2004-02-13T04:00:00+09:00     => 2004-02-13T04:00:00+09:00
// 2004-02-13T04:00:00+10:00     => 2004-02-13T03:00:00+09:00
fn local_datetime(s: &str, tz: &str) -> Option<DateTime<Tz>> {
    let tz: Tz = tz.parse().expect("Check your config.json Timezone");
    match s.len() {
        10 => NaiveDate::parse_from_str(s, "%Y-%m-%d")
            .ok()
            .and_then(|dt| Some(dt.and_hms(0, 0, 0)))
            .and_then(|dt| Some(tz.from_local_datetime(&dt).unwrap())),
        19 => NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S")
            .ok()
            .and_then(|dt| Some(tz.from_local_datetime(&dt).unwrap())),
        25 => DateTime::parse_from_rfc3339(s), // ParseResult<DateTime<FixedOffset>>

        _ => None,
    }
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Linca
  • 51
  • 6

1 Answers1

2

The with_timezone() method returns DateTime<Tz2>

// tz is Asia/Tokyo
// 2004-02-13                    => 2004-02-13T00:00:00+09:00
// 2004-02-13T04:00:00           => 2004-02-13T04:00:00+09:00
// 2004-02-13T04:00:00           => 2004-02-13T04:00:00+09:00
// 2004-02-13T04:00:00+09:00     => 2004-02-13T04:00:00+09:00
// 2004-02-13T04:00:00+10:00     => 2004-02-13T03:00:00+09:00
fn local_datetime(s: &str, tz: &str) -> Option<DateTime<Tz>> {
    let tz: Tz = tz.parse().expect("Check your config.json Timezone");
    match s.len() {
        10 => NaiveDate::parse_from_str(s, "%Y-%m-%d")
            .ok()
            .and_then(|dt| Some(dt.and_hms(0, 0, 0)))
            .and_then(|dt| Some(tz.from_local_datetime(&dt).unwrap())),
        19 => NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S")
            .ok()
            .and_then(|dt| Some(tz.from_local_datetime(&dt).unwrap())),
        25 => DateTime::parse_from_rfc3339(s)
            .ok() // ParseResult<DateTime<FixedOffset>>
            .and_then(|dt| Some(dt.with_timezone(&tz))),
        _ => None,
    }
}
println!(
    "{:?}",
    local_datetime("2004-02-13T04:00:00+09:00", "Asia/Tokyo")
);
// => Some(2004-02-13T04:00:00JST)
println!(
    "{:?}",
    local_datetime("2004-02-13T04:00:00+09:00", "Asia/Taipei")
);
// => Some(2004-02-13T03:00:00CST)
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Linca
  • 51
  • 6