Crates.io | speedate |
lib.rs | speedate |
version | 0.14.4 |
source | src |
created_at | 2022-05-31 17:43:55.443983 |
updated_at | 2024-07-03 16:02:33.364214 |
description | Fast and simple datetime, date, time and duration parsing |
homepage | https://github.com/pydantic/speedate/ |
repository | https://github.com/pydantic/speedate/ |
max_upload_size | |
id | 597635 |
size | 162,889 |
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:
YYYY-MM-DD
HH:MM:SS
HH:MM:SS.FFFFFF
1 to 6 digits are reflected in the time.microsecond
, extra digits are ignoredHH:MM
YYYY-MM-DDTHH:MM:SS
- all the above time formats are allowed for the time partYYYY-MM-DD HH:MM:SS
- T
, t
,
and _
are allowed as separatorsYYYY-MM-DDTHH:MM:SSZ
- Z
or z
is allowed as timezoneYYYY-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)YYYY-MM-DDTHH:MM:SS+0800
- the colon (:
) in the timezone is optionalPnYnMnDTnHnMnS
- ISO 8601 duration format,
see wikipedia for more details, W
for weeks is also allowedHH:MM:SS
- any of the above time formats are allowed to represent a durationD days, HH:MM:SS
- time prefixed by X days
, case-insensitive, spaces s
and ,
are all optionalD d, HH:MM:SS
- time prefixed by X d
, case-insensitive, spaces and ,
are optional±...
- 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 for each struct for more details.
This will be the datetime parsing logic for pydantic-core.
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
:
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");
speedate is significantly faster than
chrono's parse_from_rfc3339
and iso8601.
Micro-benchmarking from benches/main.rs
:
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)
ISO8601 allows many 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.