diff --git a/Makefile b/Makefile index ea04ef4..901e3d7 100644 --- a/Makefile +++ b/Makefile @@ -9,3 +9,23 @@ authors: echo >> AUTHORS.txt git log --format='%aN <%aE>' | grep -v 'Kang Seonghoon' | sort -u >> AUTHORS.txt +.PHONY: readme +readme: README.md + +README.md: src/lib.rs + # really, really sorry for this mess. + awk '/^# Chrono /{print "[Chrono][doc]",$$3}' $< > $@ + awk '/^# Chrono /{print "[Chrono][doc]",$$3}' $< | sed 's/./=/g' >> $@ + echo >> $@ + echo '[![Chrono on Travis CI][travis-image]][travis]' >> $@ + echo >> $@ + echo '[travis-image]: https://travis-ci.org/lifthrasiir/rust-chrono.png' >> $@ + echo '[travis]: https://travis-ci.org/lifthrasiir/rust-chrono' >> $@ + awk '/^# Chrono /,/^## /' $< | tail -n +2 | head -n -2 >> $@ + echo >> $@ + echo '[Complete Documentation][doc]' >> $@ + echo >> $@ + echo '[doc]: https://lifthrasiir.github.io/rust-chrono/' >> $@ + echo >> $@ + awk '/^## /,/^\*\/$$/' $< | grep -v '^# ' | head -n -2 >> $@ + diff --git a/README.md b/README.md index 1e1eebf..e4bf896 100644 --- a/README.md +++ b/README.md @@ -56,8 +56,8 @@ Chrono provides a `DateTime` type for the combined date and time. must be constructed from the `TimeZone` object. `DateTime`s with different time zones do not mix, but can be converted to each other. -You can get the current date and time in the UTC timezone (`UTC::now()`) -or in the local timezone (`Local::now()`). +You can get the current date and time in the UTC time zone (`UTC::now()`) +or in the local time zone (`Local::now()`). ~~~~ {.rust} use chrono::*; @@ -88,6 +88,12 @@ assert_eq!(UTC.ymd_opt(2014, 7, 8).and_hms_opt(21, 15, 33), LocalResult::Single(UTC.ymd(2014, 7, 8).and_hms(21, 15, 33))); assert_eq!(UTC.ymd_opt(2014, 7, 8).and_hms_opt(80, 15, 33), LocalResult::None); assert_eq!(UTC.ymd_opt(2014, 7, 38).and_hms_opt(21, 15, 33), LocalResult::None); + +// other time zone objects can be used to construct a local datetime. +// obviously, `local_dt` is normally different from `dt`, but `fixed_dt` should be identical. +let local_dt = Local.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12); +let fixed_dt = FixedOffset::east(9 * 3600).ymd(2014, 7, 8).and_hms_milli(18, 10, 11, 12); +assert_eq!(dt, fixed_dt); ~~~~ Various properties are available to the date and time, and can be altered individually. @@ -149,7 +155,7 @@ assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z"); Parsing can be done with three methods: 1. The standard `FromStr` trait (and `parse` method on a string) can be used for - parsing `DateTime` and `DateTime` values. + parsing `DateTime`, `DateTime` and `DateTime` values. This parses what the `{:?}` (`std::fmt::Debug`) format specifier prints, and requires the offset to be present. @@ -168,10 +174,12 @@ More detailed control over the parsing process is available via `format` module. use chrono::*; let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9); +let fixed_dt = dt.with_timezone(&FixedOffset::east(9*3600)); // method 1 assert_eq!("2014-11-28T12:00:09Z".parse::>(), Ok(dt.clone())); assert_eq!("2014-11-28T21:00:09+09:00".parse::>(), Ok(dt.clone())); +assert_eq!("2014-11-28T21:00:09+09:00".parse::>(), Ok(fixed_dt.clone())); // method 2 assert_eq!(UTC.datetime_from_str("2014-11-28 12:00:09", "%Y-%m-%d %H:%M:%S"), Ok(dt.clone())); @@ -179,7 +187,7 @@ assert_eq!(UTC.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"), // method 3 assert_eq!(DateTime::parse_from_str("2014-11-28 21:00:09 +09:00", "%Y-%m-%d %H:%M:%S %z"), - Ok(dt.with_timezone(&FixedOffset::east(9*3600)))); + Ok(fixed_dt.clone())); // oops, the year is missing! assert!(UTC.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T %Y").is_err()); @@ -238,4 +246,3 @@ For example, "a month later" of 2014-01-30 is not well-defined and consequently `UTC.ymd(2014, 1, 30).with_month(2)` returns `None`. Advanced time zone handling is not yet supported (but is planned in 0.3). - diff --git a/src/datetime.rs b/src/datetime.rs index 06692ff..5551352 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -13,6 +13,7 @@ use std::ops::{Add, Sub}; use {Weekday, Timelike, Datelike}; use offset::{TimeZone, Offset}; use offset::utc::UTC; +use offset::local::Local; use offset::fixed::FixedOffset; use duration::Duration; use naive::datetime::NaiveDateTime; @@ -305,13 +306,17 @@ impl str::FromStr for DateTime { type Err = ParseError; fn from_str(s: &str) -> ParseResult> { - // we parse non-UTC time zones then convert them into UTC - let dt: DateTime = try!(s.parse()); - Ok(dt.with_timezone(&UTC)) + s.parse::>().map(|dt| dt.with_timezone(&UTC)) } } -// TODO: FromStr for DateTime is quite hard without a new offset design +impl str::FromStr for DateTime { + type Err = ParseError; + + fn from_str(s: &str) -> ParseResult> { + s.parse::>().map(|dt| dt.with_timezone(&Local)) + } +} #[cfg(test)] mod tests { @@ -362,6 +367,8 @@ mod tests { assert_eq!("2015-2-18T13:16:9.15-10:00".parse::>(), Ok(UTC.ymd(2015, 2, 18).and_hms_milli(23, 16, 9, 150))); assert!("2015-2-18T23:16:9.15".parse::>().is_err()); + + // no test for `DateTime`, we cannot verify that much. } #[test] diff --git a/src/lib.rs b/src/lib.rs index 02b1f11..6ef0708 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,8 +52,8 @@ Chrono provides a `DateTime` type for the combined date and time. must be constructed from the `TimeZone` object. `DateTime`s with different time zones do not mix, but can be converted to each other. -You can get the current date and time in the UTC timezone (`UTC::now()`) -or in the local timezone (`Local::now()`). +You can get the current date and time in the UTC time zone (`UTC::now()`) +or in the local time zone (`Local::now()`). ~~~~ {.rust} use chrono::*; @@ -85,6 +85,13 @@ assert_eq!(UTC.ymd_opt(2014, 7, 8).and_hms_opt(21, 15, 33), LocalResult::Single(UTC.ymd(2014, 7, 8).and_hms(21, 15, 33))); assert_eq!(UTC.ymd_opt(2014, 7, 8).and_hms_opt(80, 15, 33), LocalResult::None); assert_eq!(UTC.ymd_opt(2014, 7, 38).and_hms_opt(21, 15, 33), LocalResult::None); + +// other time zone objects can be used to construct a local datetime. +// obviously, `local_dt` is normally different from `dt`, but `fixed_dt` should be identical. +let local_dt = Local.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12); +let fixed_dt = FixedOffset::east(9 * 3600).ymd(2014, 7, 8).and_hms_milli(18, 10, 11, 12); +assert_eq!(dt, fixed_dt); +# let _ = local_dt; ~~~~ Various properties are available to the date and time, and can be altered individually. @@ -149,7 +156,7 @@ assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z"); Parsing can be done with three methods: 1. The standard `FromStr` trait (and `parse` method on a string) can be used for - parsing `DateTime` and `DateTime` values. + parsing `DateTime`, `DateTime` and `DateTime` values. This parses what the `{:?}` (`std::fmt::Debug`) format specifier prints, and requires the offset to be present. @@ -168,10 +175,12 @@ More detailed control over the parsing process is available via `format` module. use chrono::*; let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9); +let fixed_dt = dt.with_timezone(&FixedOffset::east(9*3600)); // method 1 assert_eq!("2014-11-28T12:00:09Z".parse::>(), Ok(dt.clone())); assert_eq!("2014-11-28T21:00:09+09:00".parse::>(), Ok(dt.clone())); +assert_eq!("2014-11-28T21:00:09+09:00".parse::>(), Ok(fixed_dt.clone())); // method 2 assert_eq!(UTC.datetime_from_str("2014-11-28 12:00:09", "%Y-%m-%d %H:%M:%S"), Ok(dt.clone())); @@ -179,7 +188,7 @@ assert_eq!(UTC.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"), // method 3 assert_eq!(DateTime::parse_from_str("2014-11-28 21:00:09 +09:00", "%Y-%m-%d %H:%M:%S %z"), - Ok(dt.with_timezone(&FixedOffset::east(9*3600)))); + Ok(fixed_dt.clone())); // oops, the year is missing! assert!(UTC.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T %Y").is_err());