Skip to content

Commit d82c847

Browse files
authored
ISO 8601 parsing/formatting for RelativeDuration (#14)
* implement iso 8601 parser for RelativeDuration * implement iso 8601 formatter for RelativeDuration * document iso 8601 parser and formatter * support nanoseconds in duration parser * use correct integer types in RelativeDuration parser * check for integer overflow in RelativeDuration parser * use u32 to represent nanos, to follow chrono::Duration::new signature * support nanoseconds in RelativeDuration formatter * simplify format_spec and improve efficiency * make divmod clearer in RelativeDuration::to_iso_8601 * more test cases for RelativeDuration iso parse/format * add benchmarks for RelativeDuration format/parse * fix quirks of nanosecond handling in RelativeDuration parsing/formatting * add property tests for RelativeDuration parser and formatter
1 parent 36fb183 commit d82c847

File tree

4 files changed

+422
-0
lines changed

4 files changed

+422
-0
lines changed

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ version = "0.2.6"
1717
[dev-dependencies]
1818
criterion = "0.3"
1919
chrono-tz = "0.8.3"
20+
proptest = "1.4.0"
2021

2122
[[bench]]
2223
name = "delta"
2324
harness = false
25+
26+
[[bench]]
27+
name = "relative_duration"
28+
harness = false

benches/relative_duration.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
2+
3+
use chronoutil::RelativeDuration;
4+
5+
fn relative_duration_format_benchmark(c: &mut Criterion) {
6+
let durations = [
7+
"P1M",
8+
"P1Y1M1W1DT1H1M1S",
9+
"P99999999Y11M30DT23H59M59.999999999S",
10+
]
11+
.iter()
12+
.map(|s| RelativeDuration::from_iso_8601(s).unwrap())
13+
.collect::<Vec<RelativeDuration>>();
14+
15+
let mut g = c.benchmark_group("relative_duration_format");
16+
17+
g.bench_function("one_specifier", |b| {
18+
b.iter(|| black_box(durations[0]).to_iso_8601())
19+
});
20+
g.bench_function("all_specifiers", |b| {
21+
b.iter(|| black_box(durations[1]).to_iso_8601())
22+
});
23+
g.bench_function("long_specifiers", |b| {
24+
b.iter(|| black_box(durations[2]).to_iso_8601())
25+
});
26+
}
27+
28+
fn relative_duration_parse_benchmark(c: &mut Criterion) {
29+
let durations = [
30+
"P1M",
31+
"P1Y1M1W1DT1H1M1S",
32+
"P99999999Y11M30DT23H59M59.999999999S",
33+
];
34+
35+
let mut g = c.benchmark_group("relative_duration_parse");
36+
37+
g.bench_function("one_specifier", |b| {
38+
b.iter(|| RelativeDuration::from_iso_8601(black_box(durations[0])))
39+
});
40+
g.bench_function("all_specifiers", |b| {
41+
b.iter(|| RelativeDuration::from_iso_8601(black_box(durations[1])))
42+
});
43+
g.bench_function("long_specifiers", |b| {
44+
b.iter(|| RelativeDuration::from_iso_8601(black_box(durations[2])))
45+
});
46+
}
47+
48+
criterion_group!(
49+
benches,
50+
relative_duration_format_benchmark,
51+
relative_duration_parse_benchmark
52+
);
53+
criterion_main!(benches);

src/relative_duration.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use chrono::{Date, DateTime, Duration, NaiveDate, NaiveDateTime, TimeZone};
66

77
use super::delta::shift_months;
88

9+
mod parse;
10+
911
/// Relative time duration extending Chrono's Duration.
1012
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
1113
pub struct RelativeDuration {

0 commit comments

Comments
 (0)