From 142712900fb788fd2874dd2bf9ff0ea977a5288d Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Wed, 13 Nov 2019 23:12:47 -0500 Subject: [PATCH] Attempt to read timezones from chrono-tz --- Cargo.toml | 1 + src/lib.rs | 19 ++++++++++++++----- src/tests/mod.rs | 1 + src/tests/tz.rs | 20 ++++++++++++++++++++ 4 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 src/tests/tz.rs diff --git a/Cargo.toml b/Cargo.toml index 5df44ac..7207e7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ name = "dtparse" [dependencies] chrono = "0.4" +chrono-tz = "0.5" lazy_static = "1.1" num-traits = "0.2" rust_decimal = "^0.10.1" diff --git a/src/lib.rs b/src/lib.rs index 2ebad81..0ba5381 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,6 +73,7 @@ extern crate lazy_static; extern crate chrono; +extern crate chrono_tz; extern crate num_traits; extern crate rust_decimal; @@ -83,7 +84,10 @@ use chrono::Local; use chrono::NaiveDate; use chrono::NaiveDateTime; use chrono::NaiveTime; +use chrono::Offset; use chrono::Timelike; +use chrono::TimeZone; +use chrono_tz::Tz; use num_traits::cast::ToPrimitive; use rust_decimal::Decimal; use rust_decimal::Error as DecimalError; @@ -948,11 +952,10 @@ impl Parser { fn build_tzaware( &self, - _dt: &NaiveDateTime, + dt: &NaiveDateTime, res: &ParsingResult, tzinfos: &HashMap, ) -> ParseResult> { - // TODO: Actual timezone support if let Some(offset) = res.tzoffset { Ok(Some(FixedOffset::east(offset))) } else if res.tzoffset == None @@ -965,9 +968,15 @@ impl Parser { *tzinfos.get(res.tzname.as_ref().unwrap()).unwrap(), ))) } else if res.tzname.is_some() { - // TODO: Dateutil issues a warning/deprecation notice here. Should we force the issue? - println!("tzname {} identified but not understood. Ignoring for the time being, but behavior is subject to change.", res.tzname.as_ref().unwrap()); - Ok(None) + let tzname = res.tzname.as_ref().unwrap(); + let tz: Result = tzname.parse(); + if tz.is_ok() { + let offset = tz.unwrap().offset_from_local_datetime(dt).unwrap().fix(); + Ok(Some(offset)) + } else { + println!("tzname {} identified but not understood ({}). Ignoring for the time being, but behavior is subject to change.", tzname, tz.unwrap_err()); + Ok(None) + } } else { Err(ParseError::TimezoneUnsupported) } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 1776124..9ea7f0f 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1,3 +1,4 @@ mod fuzzing; mod pycompat_parser; mod pycompat_tokenizer; +mod tz; diff --git a/src/tests/tz.rs b/src/tests/tz.rs new file mode 100644 index 0000000..8e866f3 --- /dev/null +++ b/src/tests/tz.rs @@ -0,0 +1,20 @@ +use crate::parse; + +#[test] +fn est() { + // Issue originally reported in https://github.com/bspeice/dtparse/issues/18 + let dt = parse("Fri, 21 Aug 2015 18:37:44 EST"); + + assert!(dt.is_ok()); + assert!(dt.unwrap().1.is_some()); +} + +#[test] +fn cest() { + // Issue originally reported in https://github.com/bspeice/dtparse/issues/18 + let dt = parse("Fri, 21 Aug 2015 18:37:44 CEST"); + + assert!(dt.is_ok()); + // TODO: Fix + // assert!(dt.unwrap().1.is_some()); +}