speedate

CI Coverage

Fast and simple datetime, date, time and duration parsing for rust.

speedate is a lax† RFC 3339 date and time parser, in other words, it parses common ISO 8601 formats.

- all relaxations of from RFC 3339 are compliant with ISO 8601.

The following formats are supported: * Date: YYYY-MM-DD * Time: HH:MM:SS * Time: HH:MM:SS.FFFFFF 1 to 6 digits are allowed * Time: HH:MM * Date time: YYYY-MM-DDTHH:MM:SS - all the above time formats are allowed for the time part * Date time: YYYY-MM-DD HH:MM:SS - T, t, and _ are allowed as separators * Date time: YYYY-MM-DDTHH:MM:SSZ - Z or z is allowed as timezone * Date time: YYYY-MM-DDTHH:MM:SS+08:00- positive and negative timezone are allowed, as per ISO 8601, U+2212 minus is allowed as well as ascii minus - (U+002D) * Date time: YYYY-MM-DDTHH:MM:SS+0800 - the colon (:) in the timezone is optional * Duration: PnYnMnDTnHnMnS - ISO 8601 duration format, see wikipedia for more details, W for weeks is also allowed * Duration: HH:MM:SS - any of the above time formats are allowed to represent a duration * Duration: D days, HH:MM:SS - time prefixed by X days, case-insensitive, spaces s and , are all optional * Duration: D d, HH:MM:SS - time prefixed by X d, case-insensitive, spaces and , are optional * Duration: ±... - all duration formats shown here can be prefixed with + or - to indicate positive and negative durations respectively

This will be the datetime parsing logic for pydantic-core.

Usage

```rust use speedate::{DateTime, Date, Time};

fn main() { let dt = DateTime::parsestr("2022-01-01T12:13:14Z").unwrap(); asserteq!( dt, DateTime { date: Date { year: 2022, month: 1, day: 1, }, time: Time { hour: 12, minute: 13, second: 14, microsecond: 0, }, offset: Some(0), } ); asserteq!(dt.tostring(), "2022-01-01T12:13:14Z"); } ```

Performance

speedate is significantly faster than chrono's parse_from_rfc3339 and iso8601.

Micro-benchmarking from benches/main.rs:

text test datetime_error_speedate ... bench: 6 ns/iter (+/- 0) test datetime_error_chrono ... bench: 48 ns/iter (+/- 0) test datetime_error_iso8601 ... bench: 118 ns/iter (+/- 2) test datetime_ok_speedate ... bench: 9 ns/iter (+/- 0) test datetime_ok_chrono ... bench: 62 ns/iter (+/- 0) test datetime_ok_iso8601 ... bench: 77 ns/iter (+/- 1) test duration_ok_speedate ... bench: 23 ns/iter (+/- 0) test duration_ok_iso8601 ... bench: 48 ns/iter (+/- 0)

Why not full iso8601?

ISO8601 has lots of allowed formats, see ijmacd.github.io/rfc3339-iso8601.

Most of these are unknown to most users, and not desired. This library aims to support the most common formats without introducing ambiguity.