renamed `from_str` methods to `parse_from_str`.

so that we can safely implement `FromStr` traits for those types.
also updates READMEs and rewires `%+` specifier of `StrftimeItems`
to a new RFC 3339 formatting item.
This commit is contained in:
Kang Seonghoon 2015-02-15 21:26:11 +09:00
parent 6937470405
commit 637784c8ef
8 changed files with 71 additions and 41 deletions

View File

@ -25,6 +25,21 @@ which Chrono builts upon and should acknowledge:
[doc]: https://lifthrasiir.github.io/rust-chrono/ [doc]: https://lifthrasiir.github.io/rust-chrono/
## Usage
Put this in your `Cargo.toml`:
```toml
[dependencies]
chrono = "0.2"
```
And this in your crate root:
```toml
extern crate chrono;
```
## Overview ## Overview
### Duration ### Duration
@ -132,7 +147,8 @@ assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
Parsing can be done with two methods: Parsing can be done with two methods:
- `DateTime::from_str` parses a date and time with offsets and returns `DateTime<FixedOffset>`. - `DateTime::parse_from_str` parses a date and time with offsets and
returns `DateTime<FixedOffset>`.
This should be used when the offset is a part of input and the caller cannot guess that. This should be used when the offset is a part of input and the caller cannot guess that.
It *cannot* be used when the offset can be missing. It *cannot* be used when the offset can be missing.
@ -148,8 +164,8 @@ use chrono::{UTC, Offset, DateTime};
let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9); let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9);
assert_eq!(UTC.datetime_from_str("2014-11-28 12:00:09", "%Y-%m-%d %H:%M:%S"), Ok(dt.clone())); assert_eq!(UTC.datetime_from_str("2014-11-28 12:00:09", "%Y-%m-%d %H:%M:%S"), Ok(dt.clone()));
assert_eq!(UTC.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"), Ok(dt.clone())); assert_eq!(UTC.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"), Ok(dt.clone()));
assert_eq!(DateTime::from_str("2014-11-28 21:00:09 +09:00", assert_eq!(DateTime::parse_from_str("2014-11-28 21:00:09 +09:00",
"%Y-%m-%d %H:%M:%S %z").map(|dt| dt.with_offset(UTC)), Ok(dt)); "%Y-%m-%d %H:%M:%S %z").map(|dt| dt.with_offset(UTC)), Ok(dt));
// oops, the year is missing! // oops, the year is missing!
assert!(UTC.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T %Y").is_err()); assert!(UTC.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T %Y").is_err());
@ -208,4 +224,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`. and consequently `UTC.ymd(2014, 1, 30).with_month(2)` returns `None`.
Advanced offset handling is not yet supported (but is planned in 0.3). Advanced offset handling is not yet supported (but is planned in 0.3).

View File

@ -94,7 +94,7 @@ impl DateTime<FixedOffset> {
/// See the `format::strftime` module on the supported escape sequences. /// See the `format::strftime` module on the supported escape sequences.
/// ///
/// See also `Offset::datetime_from_str` which gives a local `DateTime` on specific time zone. /// See also `Offset::datetime_from_str` which gives a local `DateTime` on specific time zone.
pub fn from_str(s: &str, fmt: &str) -> ParseResult<DateTime<FixedOffset>> { pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<DateTime<FixedOffset>> {
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); try!(parse(&mut parsed, s, StrftimeItems::new(fmt)));
parsed.to_datetime() parsed.to_datetime()
@ -295,13 +295,13 @@ mod tests {
} }
#[test] #[test]
fn test_datetime_from_str() { fn test_datetime_parse_from_str() {
let ymdhms = |&: y,m,d,h,n,s,off| FixedOffset::east(off).ymd(y,m,d).and_hms(h,n,s); let ymdhms = |&: y,m,d,h,n,s,off| FixedOffset::east(off).ymd(y,m,d).and_hms(h,n,s);
assert_eq!(DateTime::from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"), assert_eq!(DateTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
Ok(ymdhms(2014, 5, 7, 12, 34, 56, 570*60))); // ignore offset Ok(ymdhms(2014, 5, 7, 12, 34, 56, 570*60))); // ignore offset
assert!(DateTime::from_str("20140507000000", "%Y%m%d%H%M%S").is_err()); // no offset assert!(DateTime::parse_from_str("20140507000000", "%Y%m%d%H%M%S").is_err()); // no offset
assert!(DateTime::from_str("Fri, 09 Aug 2013 23:54:35 GMT", assert!(DateTime::parse_from_str("Fri, 09 Aug 2013 23:54:35 GMT",
"%a, %d %b %Y %H:%M:%S GMT").is_err()); "%a, %d %b %Y %H:%M:%S GMT").is_err());
assert_eq!(UTC.datetime_from_str("Fri, 09 Aug 2013 23:54:35 GMT", assert_eq!(UTC.datetime_from_str("Fri, 09 Aug 2013 23:54:35 GMT",
"%a, %d %b %Y %H:%M:%S GMT"), "%a, %d %b %Y %H:%M:%S GMT"),
Ok(UTC.ymd(2013, 8, 9).and_hms(23, 54, 35))); Ok(UTC.ymd(2013, 8, 9).and_hms(23, 54, 35)));

View File

@ -84,7 +84,7 @@ Spec. Example Description
%c Sun Jul 8 00:34:60 2001 %c Sun Jul 8 00:34:60 2001
`ctime` date & time format. Same to `%a %b %e %T %Y`. (No newline!) `ctime` date & time format. Same to `%a %b %e %T %Y`. (No newline!)
%+ 2001-07-08T00:34:60+09:30 %+ 2001-07-08T00:34:60+09:30
ISO 8601 date & time format. Same to `%Y-%m-%dT%H:%M:%S%z`. ISO 8601 date & time format. Almost same to `%Y-%m-%dT%H:%M:%S%z`.
%s 994485899 UNIX timestamp, the number of seconds since 1970-01-01 00:00 UTC. %s 994485899 UNIX timestamp, the number of seconds since 1970-01-01 00:00 UTC.
This is not padded and can be negative. This is not padded and can be negative.
@ -207,9 +207,7 @@ impl<'a> Iterator for StrftimeItems<'a> {
num0!(YearMod100)]), num0!(YearMod100)]),
'y' => Some(num0!(YearMod100)), 'y' => Some(num0!(YearMod100)),
'z' => Some(fix!(TimezoneOffset)), 'z' => Some(fix!(TimezoneOffset)),
'+' => Some(recons![num!(Year), lit!("-"), num0!(Month), lit!("-"), num0!(Day), '+' => Some(fix!(RFC3339)),
lit!("T"), num0!(Hour), lit!(":"), num0!(Minute), lit!(":"),
num0!(Second), fix!(TimezoneOffset)]),
'%' => Some(lit!("%")), '%' => Some(lit!("%")),
_ => Some(Item::Error), // no such specifier _ => Some(Item::Error), // no such specifier
} }

View File

@ -21,6 +21,21 @@ which Chrono builts upon and should acknowledge:
* Dietrich Epp's [datetime-rs](https://github.com/depp/datetime-rs) * Dietrich Epp's [datetime-rs](https://github.com/depp/datetime-rs)
* Luis de Bethencourt's [rust-datetime](https://github.com/luisbg/rust-datetime) * Luis de Bethencourt's [rust-datetime](https://github.com/luisbg/rust-datetime)
## Usage
Put this in your `Cargo.toml`:
```toml
[dependencies]
chrono = "0.2"
```
And this in your crate root:
```toml
extern crate chrono;
```
## Overview ## Overview
### Duration ### Duration
@ -133,7 +148,8 @@ assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
Parsing can be done with two methods: Parsing can be done with two methods:
- `DateTime::from_str` parses a date and time with offsets and returns `DateTime<FixedOffset>`. - `DateTime::parse_from_str` parses a date and time with offsets and
returns `DateTime<FixedOffset>`.
This should be used when the offset is a part of input and the caller cannot guess that. This should be used when the offset is a part of input and the caller cannot guess that.
It *cannot* be used when the offset can be missing. It *cannot* be used when the offset can be missing.
@ -149,8 +165,8 @@ use chrono::{UTC, Offset, DateTime};
let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9); let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9);
assert_eq!(UTC.datetime_from_str("2014-11-28 12:00:09", "%Y-%m-%d %H:%M:%S"), Ok(dt.clone())); assert_eq!(UTC.datetime_from_str("2014-11-28 12:00:09", "%Y-%m-%d %H:%M:%S"), Ok(dt.clone()));
assert_eq!(UTC.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"), Ok(dt.clone())); assert_eq!(UTC.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"), Ok(dt.clone()));
assert_eq!(DateTime::from_str("2014-11-28 21:00:09 +09:00", assert_eq!(DateTime::parse_from_str("2014-11-28 21:00:09 +09:00",
"%Y-%m-%d %H:%M:%S %z").map(|dt| dt.with_offset(UTC)), Ok(dt)); "%Y-%m-%d %H:%M:%S %z").map(|dt| dt.with_offset(UTC)), Ok(dt));
// oops, the year is missing! // oops, the year is missing!
assert!(UTC.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T %Y").is_err()); assert!(UTC.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T %Y").is_err());

View File

@ -182,7 +182,7 @@ impl NaiveDate {
/// Parses a string with the specified format string and returns a new `NaiveDate`. /// Parses a string with the specified format string and returns a new `NaiveDate`.
/// See the `format::strftime` module on the supported escape sequences. /// See the `format::strftime` module on the supported escape sequences.
pub fn from_str(s: &str, fmt: &str) -> ParseResult<NaiveDate> { pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDate> {
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); try!(parse(&mut parsed, s, StrftimeItems::new(fmt)));
parsed.to_naive_date() parsed.to_naive_date()
@ -846,17 +846,17 @@ mod tests {
} }
#[test] #[test]
fn test_date_from_str() { fn test_date_parse_from_str() {
let ymd = |&: y,m,d| NaiveDate::from_ymd(y,m,d); let ymd = |&: y,m,d| NaiveDate::from_ymd(y,m,d);
assert_eq!(NaiveDate::from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"), assert_eq!(NaiveDate::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
Ok(ymd(2014, 5, 7))); // ignore time and offset Ok(ymd(2014, 5, 7))); // ignore time and offset
assert_eq!(NaiveDate::from_str("2015-W06-1=2015-033", "%G-W%V-%u = %Y-%j"), assert_eq!(NaiveDate::parse_from_str("2015-W06-1=2015-033", "%G-W%V-%u = %Y-%j"),
Ok(ymd(2015, 2, 2))); Ok(ymd(2015, 2, 2)));
assert_eq!(NaiveDate::from_str("Fri, 09 Aug 13", "%a, %d %b %y"), assert_eq!(NaiveDate::parse_from_str("Fri, 09 Aug 13", "%a, %d %b %y"),
Ok(ymd(2013, 8, 9))); Ok(ymd(2013, 8, 9)));
assert!(NaiveDate::from_str("Sat, 09 Aug 2013", "%a, %d %b %Y").is_err()); assert!(NaiveDate::parse_from_str("Sat, 09 Aug 2013", "%a, %d %b %Y").is_err());
assert!(NaiveDate::from_str("2014-57", "%Y-%m-%d").is_err()); assert!(NaiveDate::parse_from_str("2014-57", "%Y-%m-%d").is_err());
assert!(NaiveDate::from_str("2014", "%Y").is_err()); // insufficient assert!(NaiveDate::parse_from_str("2014", "%Y").is_err()); // insufficient
} }
#[test] #[test]

View File

@ -62,7 +62,7 @@ impl NaiveDateTime {
/// Parses a string with the specified format string and returns a new `NaiveDateTime`. /// Parses a string with the specified format string and returns a new `NaiveDateTime`.
/// See the `format::strftime` module on the supported escape sequences. /// See the `format::strftime` module on the supported escape sequences.
pub fn from_str(s: &str, fmt: &str) -> ParseResult<NaiveDateTime> { pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDateTime> {
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); try!(parse(&mut parsed, s, StrftimeItems::new(fmt)));
parsed.to_naive_datetime_with_offset(0) // no offset adjustment parsed.to_naive_datetime_with_offset(0) // no offset adjustment
@ -345,19 +345,19 @@ mod tests {
} }
#[test] #[test]
fn test_datetime_from_str() { fn test_datetime_parse_from_str() {
let ymdhms = |&: y,m,d,h,n,s| NaiveDate::from_ymd(y,m,d).and_hms(h,n,s); let ymdhms = |&: y,m,d,h,n,s| NaiveDate::from_ymd(y,m,d).and_hms(h,n,s);
assert_eq!(NaiveDateTime::from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"), assert_eq!(NaiveDateTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
Ok(ymdhms(2014, 5, 7, 12, 34, 56))); // ignore offset Ok(ymdhms(2014, 5, 7, 12, 34, 56))); // ignore offset
assert_eq!(NaiveDateTime::from_str("2015-W06-1 000000", "%G-W%V-%u%H%M%S"), assert_eq!(NaiveDateTime::parse_from_str("2015-W06-1 000000", "%G-W%V-%u%H%M%S"),
Ok(ymdhms(2015, 2, 2, 0, 0, 0))); Ok(ymdhms(2015, 2, 2, 0, 0, 0)));
assert_eq!(NaiveDateTime::from_str("Fri, 09 Aug 2013 23:54:35 GMT", assert_eq!(NaiveDateTime::parse_from_str("Fri, 09 Aug 2013 23:54:35 GMT",
"%a, %d %b %Y %H:%M:%S GMT"), "%a, %d %b %Y %H:%M:%S GMT"),
Ok(ymdhms(2013, 8, 9, 23, 54, 35))); Ok(ymdhms(2013, 8, 9, 23, 54, 35)));
assert!(NaiveDateTime::from_str("Sat, 09 Aug 2013 23:54:35 GMT", assert!(NaiveDateTime::parse_from_str("Sat, 09 Aug 2013 23:54:35 GMT",
"%a, %d %b %Y %H:%M:%S GMT").is_err()); "%a, %d %b %Y %H:%M:%S GMT").is_err());
assert!(NaiveDateTime::from_str("2014-5-7 12:3456", "%Y-%m-%d %H:%M:%S").is_err()); assert!(NaiveDateTime::parse_from_str("2014-5-7 12:3456", "%Y-%m-%d %H:%M:%S").is_err());
assert!(NaiveDateTime::from_str("12:34:56", "%H:%M:%S").is_err()); // insufficient assert!(NaiveDateTime::parse_from_str("12:34:56", "%H:%M:%S").is_err()); // insufficient
} }
#[test] #[test]

View File

@ -120,7 +120,7 @@ impl NaiveTime {
/// Parses a string with the specified format string and returns a new `NaiveTime`. /// Parses a string with the specified format string and returns a new `NaiveTime`.
/// See the `format::strftime` module on the supported escape sequences. /// See the `format::strftime` module on the supported escape sequences.
pub fn from_str(s: &str, fmt: &str) -> ParseResult<NaiveTime> { pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveTime> {
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); try!(parse(&mut parsed, s, StrftimeItems::new(fmt)));
parsed.to_naive_time() parsed.to_naive_time()
@ -384,13 +384,13 @@ mod tests {
} }
#[test] #[test]
fn test_time_from_str() { fn test_time_parse_from_str() {
let hms = |&: h,m,s| NaiveTime::from_hms(h,m,s); let hms = |&: h,m,s| NaiveTime::from_hms(h,m,s);
assert_eq!(NaiveTime::from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"), assert_eq!(NaiveTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
Ok(hms(12, 34, 56))); // ignore date and offset Ok(hms(12, 34, 56))); // ignore date and offset
assert_eq!(NaiveTime::from_str("PM 12:59", "%P %H:%M"), assert_eq!(NaiveTime::parse_from_str("PM 12:59", "%P %H:%M"),
Ok(hms(12, 59, 0))); Ok(hms(12, 59, 0)));
assert!(NaiveTime::from_str("12:3456", "%H:%M:%S").is_err()); assert!(NaiveTime::parse_from_str("12:3456", "%H:%M:%S").is_err());
} }
#[test] #[test]

View File

@ -299,7 +299,8 @@ pub trait Offset: Clone + fmt::Debug {
/// If the format does not include offsets, the current offset is assumed; /// If the format does not include offsets, the current offset is assumed;
/// otherwise the input should have a matching UTC offset. /// otherwise the input should have a matching UTC offset.
/// ///
/// See also `DateTime::from_str` which gives a local `DateTime` with parsed `FixedOffset`. /// See also `DateTime::parse_from_str` which gives a local `DateTime`
/// with parsed `FixedOffset`.
fn datetime_from_str(&self, s: &str, fmt: &str) -> ParseResult<DateTime<Self>> { fn datetime_from_str(&self, s: &str, fmt: &str) -> ParseResult<DateTime<Self>> {
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); try!(parse(&mut parsed, s, StrftimeItems::new(fmt)));