Skip to content

Commit

Permalink
ISO 8601 parsing/formatting for RelativeDuration (#14)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
intarga authored Apr 24, 2024
1 parent 36fb183 commit d82c847
Show file tree
Hide file tree
Showing 4 changed files with 422 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ version = "0.2.6"
[dev-dependencies]
criterion = "0.3"
chrono-tz = "0.8.3"
proptest = "1.4.0"

[[bench]]
name = "delta"
harness = false

[[bench]]
name = "relative_duration"
harness = false
53 changes: 53 additions & 0 deletions benches/relative_duration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};

use chronoutil::RelativeDuration;

fn relative_duration_format_benchmark(c: &mut Criterion) {
let durations = [
"P1M",
"P1Y1M1W1DT1H1M1S",
"P99999999Y11M30DT23H59M59.999999999S",
]
.iter()
.map(|s| RelativeDuration::from_iso_8601(s).unwrap())
.collect::<Vec<RelativeDuration>>();

let mut g = c.benchmark_group("relative_duration_format");

g.bench_function("one_specifier", |b| {
b.iter(|| black_box(durations[0]).to_iso_8601())
});
g.bench_function("all_specifiers", |b| {
b.iter(|| black_box(durations[1]).to_iso_8601())
});
g.bench_function("long_specifiers", |b| {
b.iter(|| black_box(durations[2]).to_iso_8601())
});
}

fn relative_duration_parse_benchmark(c: &mut Criterion) {
let durations = [
"P1M",
"P1Y1M1W1DT1H1M1S",
"P99999999Y11M30DT23H59M59.999999999S",
];

let mut g = c.benchmark_group("relative_duration_parse");

g.bench_function("one_specifier", |b| {
b.iter(|| RelativeDuration::from_iso_8601(black_box(durations[0])))
});
g.bench_function("all_specifiers", |b| {
b.iter(|| RelativeDuration::from_iso_8601(black_box(durations[1])))
});
g.bench_function("long_specifiers", |b| {
b.iter(|| RelativeDuration::from_iso_8601(black_box(durations[2])))
});
}

criterion_group!(
benches,
relative_duration_format_benchmark,
relative_duration_parse_benchmark
);
criterion_main!(benches);
2 changes: 2 additions & 0 deletions src/relative_duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use chrono::{Date, DateTime, Duration, NaiveDate, NaiveDateTime, TimeZone};

use super::delta::shift_months;

mod parse;

/// Relative time duration extending Chrono's Duration.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct RelativeDuration {
Expand Down
Loading

0 comments on commit d82c847

Please sign in to comment.