Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/pydantic/speedate
Fast and simple datetime, date, time and duration parsing for rust.
https://github.com/pydantic/speedate
date datetime iso8601 parse parser pydantic rfc3339 rust time timezone
Last synced: 5 days ago
JSON representation
Fast and simple datetime, date, time and duration parsing for rust.
- Host: GitHub
- URL: https://github.com/pydantic/speedate
- Owner: pydantic
- License: mit
- Created: 2022-05-24T22:26:51.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-11-01T09:02:00.000Z (12 days ago)
- Last Synced: 2024-11-01T10:17:08.763Z (12 days ago)
- Topics: date, datetime, iso8601, parse, parser, pydantic, rfc3339, rust, time, timezone
- Language: Rust
- Homepage: https://docs.rs/speedate/latest/speedate/
- Size: 166 KB
- Stars: 199
- Watchers: 12
- Forks: 19
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# speedate
[![CI](https://github.com/pydantic/speedate/actions/workflows/ci.yml/badge.svg?event=push)](https://github.com/pydantic/speedate/actions/workflows/ci.yml?query=branch%3Amain)
[![Coverage](https://codecov.io/gh/pydantic/speedate/branch/main/graph/badge.svg)](https://codecov.io/gh/pydantic/speedate)
[![Crates.io](https://img.shields.io/crates/v/speedate?color=green)](https://crates.io/crates/speedate)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](https://tools.ietf.org/html/rfc3339)
are compliant with [ISO 8601](https://en.wikipedia.org/wiki/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 reflected in the `time.microsecond`, extra digits are ignored
* 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](https://en.wikipedia.org/wiki/ISO_8601#Durations) 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 respectivelyIn addition, unix timestamps (both seconds and milliseconds) can be used to create dates and datetimes.
See [the documentation](https://docs.rs/speedate/latest/speedate/index.html#structs) for each struct for more details.
This will be the datetime parsing logic for [pydantic-core](https://github.com/pydantic/pydantic-core).
## Usage
```rust
use speedate::{DateTime, Date, Time};let dt = DateTime::parse_str("2022-01-01T12:13:14Z").unwrap();
assert_eq!(
dt,
DateTime {
date: Date {
year: 2022,
month: 1,
day: 1,
},
time: Time {
hour: 12,
minute: 13,
second: 14,
microsecond: 0,
tz_offset: Some(0),
},
}
);
assert_eq!(dt.to_string(), "2022-01-01T12:13:14Z");
```To control the specifics of time parsing you can use provide a `TimeConfig`:
```rust
use speedate::{DateTime, Date, Time, TimeConfig, MicrosecondsPrecisionOverflowBehavior};
let dt = DateTime::parse_bytes_with_config(
"1689102037.5586429".as_bytes(),
&TimeConfig::builder()
.unix_timestamp_offset(Some(0))
.microseconds_precision_overflow_behavior(MicrosecondsPrecisionOverflowBehavior::Truncate)
.build(),
).unwrap();
assert_eq!(
dt,
DateTime {
date: Date {
year: 2023,
month: 7,
day: 11,
},
time: Time {
hour: 19,
minute: 0,
second: 37,
microsecond: 558643,
tz_offset: Some(0),
},
}
);
assert_eq!(dt.to_string(), "2023-07-11T19:00:37.558643Z");
```## Performance
**speedate** is significantly faster than
[chrono's `parse_from_rfc3339`](https://docs.rs/chrono/latest/chrono/struct.DateTime.html#method.parse_from_rfc3339)
and [iso8601](https://crates.io/crates/iso8601).Micro-benchmarking from [`benches/main.rs`](https://github.com/pydantic/speedate/blob/main/benches/main.rs):
```text
test datetime_error_speedate ... bench: 6 ns/iter (+/- 0)
test datetime_error_chrono ... bench: 50 ns/iter (+/- 1)
test datetime_error_iso8601 ... bench: 118 ns/iter (+/- 2)
test datetime_ok_speedate ... bench: 9 ns/iter (+/- 0)
test datetime_ok_chrono ... bench: 182 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)
test timestamp_ok_speedate ... bench: 9 ns/iter (+/- 0)
test timestamp_ok_chrono ... bench: 10 ns/iter (+/- 0)
```## Why not full iso8601?
ISO8601 allows many formats, see
[ijmacd.github.io/rfc3339-iso8601](https://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.