0.2.0-dev: date/time parsing.

Basically, this should close #12 when officially released.

- Formatting syntax is now refactored out of the rendering logic.
  The main syntax is available in the `format::strftime` module,
  which also serves as a documentation for the syntax.

- A parser (modelled after `strptime(3)`) has been implemented.
  See the individual commits for the detailed implementation.

- There are two ways to get a timezone-aware value from a string:
  `Offset` or `DateTime<FixedOffset>`. The former should be used
  when the offset is known in advance (e.g. assume the local date)
  while the latter should be used when the offset is unknown.
  Naive types have a simple `from_str` method.

- There are some known problems with the parser (even after
  tons of tests), which will be sorted out in 0.2. Known issues:

  - This does not exactly handle RFC 2822 and RFC 3339, which
    subtly differs from the current implementation in
    case-sensitivity, whitespace handling and legacy syntax.
    I'd like to integrate #24 for this cause.

  - Time zone names are not recognized at all. There is even
    no means to get a name itself, not sure about the resolution.

  - `Parsed` does *not* constrain `year` to be non-negative,
    so manually prepared `Parsed` may give a negative year.
    But the current verification pass may break such cases.

  - I absolutely don't know about the parser's performance!

- `AUTHORS.txt` has been added, for what it's worth.
This commit is contained in:
Kang Seonghoon 2015-02-05 02:37:54 +09:00
parent 7eb9a1a983
commit 82c63e5b40
6 changed files with 88 additions and 8 deletions

9
AUTHORS.txt Normal file
View File

@ -0,0 +1,9 @@
Chrono is mainly written by Kang Seonghoon <public+rust@mearie.org>,
and also the following people (in ascending order):
Colin Ray <r.colinray@gmail.com>
David Ross <daboross@daboross.net>
Eunchong Yu <kroisse@gmail.com>
Ken Tossell <ken@tossell.net>
Steve Klabnik <steve@steveklabnik.com>
klutzy <klutzytheklutzy@gmail.com>

View File

@ -1,6 +1,6 @@
[package]
name = "chrono"
version = "0.1.17"
version = "0.2.0-dev"
authors = ["Kang Seonghoon <public+rust@mearie.org>"]
description = "Date and time library for Rust"

11
Makefile Normal file
View File

@ -0,0 +1,11 @@
.PHONY: all
all:
@echo 'Try `cargo build` instead.'
.PHONY: authors
authors:
echo 'Chrono is mainly written by Kang Seonghoon <public+rust@mearie.org>,' > AUTHORS.txt
echo 'and also the following people (in ascending order):' >> AUTHORS.txt
echo >> AUTHORS.txt
git log --format='%aN <%aE>' | grep -v 'Kang Seonghoon' | sort -u >> AUTHORS.txt

View File

@ -1,5 +1,5 @@
[Chrono][doc] 0.1.17
====================
[Chrono][doc] 0.2.0-dev
=======================
[![Chrono on Travis CI][travis-image]][travis]
@ -115,6 +115,7 @@ assert_eq!(UTC.ymd(1970, 1, 1).and_hms(0, 0, 0) - Duration::seconds(1_000_000_00
Formatting is done via the `format` method,
which format is equivalent to the familiar `strftime` format.
(See the `format::strftime` module documentation for full syntax.)
The default `to_string` method and `{:?}` specifier also give a reasonable representation.
~~~~ {.rust}
@ -129,6 +130,35 @@ assert_eq!(dt.to_string(), "2014-11-28 12:00:09 UTC");
assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
~~~~
Parsing can be done with two methods:
- `DateTime::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.
It *cannot* be used when the offset can be missing.
- `Offset::datetime_from_str` is similar but returns `DateTime` of given offset.
When the explicit offset is missing from the input, it simply uses given offset.
It issues an error when the input contains an explicit offset different from the current offset.
More detailed control over the parsing process is available via `format` module.
~~~~ {.rust}
use chrono::{UTC, Offset, DateTime};
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("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",
"%Y-%m-%d %H:%M:%S %z").map(|dt| dt.with_offset(UTC)), Ok(dt));
// oops, the year is missing!
assert!(UTC.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T %Y").is_err());
// oops, the format string does not include the year at all!
assert!(UTC.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T").is_err());
// oops, the weekday is incorrect!
assert!(UTC.datetime_from_str("Sat Nov 28 12:00:09 2014", "%a %b %e %T %Y").is_err());
~~~~
### Individual date and time
Chrono also provides an individual date type (`Date`) and time type (`Time`).
@ -177,5 +207,5 @@ Any operation that can be ambiguous will return `None` in such cases.
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 offset handling and date/time parsing is not yet supported (but is planned).
Advanced offset handling is not yet supported (but is planned in 0.3).

View File

@ -24,14 +24,14 @@ Spec. Example Description
%m 07 Month number (01--12), zero-padded to 2 digits.
%b Jul Abbreviated month name. Always 3 letters.
%B July Full month name.
%B July Full month name. Also accepts corresponding abbreviation in parsing.
%h Jul Same to `%b`.
%d 08 Day number (01--31), zero-padded to 2 digits.
%e 8 Same to `%d` but space-padded.
%a Sun Abbreviated weekday name. Always 3 letters.
%A Sunday Full weekday name.
%A Sunday Full weekday name. Also accepts corresponding abbreviation in parsing.
%w 0 Sunday = 0, Monday = 1, ..., Saturday = 6.
%u 7 Monday = 1, Tuesday = 2, ..., Sunday = 7. (ISO 8601)

View File

@ -4,7 +4,7 @@
/*!
# Chrono 0.1.17
# Chrono 0.2.0-dev
Date and time handling for Rust. (also known as `rust-chrono`)
It aims to be a feature-complete superset of the [time](https://github.com/rust-lang/time) library.
@ -116,6 +116,7 @@ assert_eq!(UTC.ymd(1970, 1, 1).and_hms(0, 0, 0) - Duration::seconds(1_000_000_00
Formatting is done via the `format` method,
which format is equivalent to the familiar `strftime` format.
(See the `format::strftime` module documentation for full syntax.)
The default `to_string` method and `{:?}` specifier also give a reasonable representation.
~~~~ {.rust}
@ -130,6 +131,35 @@ assert_eq!(dt.to_string(), "2014-11-28 12:00:09 UTC");
assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
~~~~
Parsing can be done with two methods:
- `DateTime::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.
It *cannot* be used when the offset can be missing.
- `Offset::datetime_from_str` is similar but returns `DateTime` of given offset.
When the explicit offset is missing from the input, it simply uses given offset.
It issues an error when the input contains an explicit offset different from the current offset.
More detailed control over the parsing process is available via `format` module.
~~~~ {.rust}
use chrono::{UTC, Offset, DateTime};
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("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",
"%Y-%m-%d %H:%M:%S %z").map(|dt| dt.with_offset(UTC)), Ok(dt));
// oops, the year is missing!
assert!(UTC.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T %Y").is_err());
// oops, the format string does not include the year at all!
assert!(UTC.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T").is_err());
// oops, the weekday is incorrect!
assert!(UTC.datetime_from_str("Sat Nov 28 12:00:09 2014", "%a %b %e %T %Y").is_err());
~~~~
### Individual date and time
Chrono also provides an individual date type (`Date`) and time type (`Time`).
@ -179,7 +209,7 @@ Any operation that can be ambiguous will return `None` in such cases.
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 offset handling and date/time parsing is not yet supported (but is planned).
Advanced offset handling is not yet supported (but is planned in 0.3).
*/