4 stable releases

Uses new Rust 2024

new 1.0.7 Mar 11, 2025
1.0.6 Mar 6, 2025
1.0.3 Mar 5, 2025
1.0.0 Mar 4, 2025

#295 in Rust patterns

Download history 180/week @ 2025-02-27 479/week @ 2025-03-06

659 downloads per month

MIT license

57KB
1K SLoC

relative-duration

build coverage docs.rs crates.io

A duration (the std style) that can retain negative values. Shipped with the standard set of operators for basic math.

use relative_duration::suffix::Suffix;

let a = 10.milliseconds();
let b = 20.milliseconds();
let c = a - b;

assert_eq!(c, -10.milliseconds());

Reason

The existence of this (rather simple) crate is for calculus purposes only. Sometimes, when you work with offsets of timed events, you need to go backwards in time (shifting an event to the "left" for exemple).

when you try to do it on std durations, you get a panic.

use std::panic::catch_unwind;
use std::time::Duration;

let a = Duration::from_millis(10);
let b = Duration::from_millis(20);

let res = catch_unwind(|| {
    let c = a - b;
});

assert!(res.is_err()); // The thing has panicked... we lost :'(

That's because durations in the std library are meant to represent a delta between two instants, and instants are guaranteed to not go backwards.

The typical use case of this crate is when you want to do calculus with durations that can be negative without using formatting oriented types as with chrono, or resort to using bare numerical representations that take away the flexibility of the Duration type.

Features

Comparison

Relative duration objects can be compared like standard durations

use relative_duration::prelude::*;

let a = RelativeDuration::from_secs(-10);
let b = RelativeDuration::from_secs(20);

assert!(b > a);

Basic operations

As this crate is really meant for calculus, basic operations are handled

use relative_duration::prelude::*;

let a = RelativeDuration::from_millis(10);
let b = RelativeDuration::from_millis(20);
let c = a + b;
let d = c - RelativeDuration::from_millis(-50);

assert_eq!(c, RelativeDuration::from_millis(30));
assert_eq!(d, RelativeDuration::from_millis(80));

as well as divisions and multiplication by an unsigned integer scalar

use relative_duration::prelude::*;

let a = 2u32 * RelativeDuration::from_millis(10);
assert_eq!(a, RelativeDuration::from_millis(20));

let b = RelativeDuration::from_millis(30) / 2;
assert_eq!(b, RelativeDuration::from_millis(15));

and methods that mirror those of std duration.

Duration division

It is possible to divide durations by other durations

use relative_duration::prelude::*;

let f1 = RelativeDuration::from_millis(100).div_duration_f32(RelativeDuration::from_millis(10));

assert_eq!(f1, 10.0);

Handy things

This crate has a trait called Suffix. It helps create relative durations from a bunch of primitives (kotlin style)

use relative_duration::prelude::*;

let d = 10.microseconds();

assert_eq!(d, RelativeDuration::from_micros(10));

exists for nanoseconds, microseconds, milliseconds and seconds.

No runtime deps