Crate float_duration [] [src]

Temporal quantification using floating-point quantities.

This crate provides quantification for spans of time. Unlike the standard std::time or the chrono crate, this crate aims to provide a fully featured Duration type which exposes and uses floating-point values instead of integer ones.

The existing solutions for time spans are high precision and good for displaying and storing time values, but they are less than convenient to use in simulations or mathematical contexts where a single fractional value in some unit is needed. Thus, this crate was developed in order to fill that need while being maximally compatible with the existing time libraries and not re-inventing the wheel. The interface aims to be very similar to these libraries, just using floating point values so it may be used as a near drop-in replacement for existing programs that would benefit from floating point durations.

The goal is to provide a type with the same set of features and flexibility as std::chrono::duration in C++ while being "Rusty" in design.

Usage

Put this in your Cargo.toml:

[dependencies]
float_duration = "0.3.3"

Overview

This crate provides a single primary type: FloatDuration which represents an arbitrary distance in time with no defined start or end point. Internally, it stores a single f64 holding the number of seconds the duration represents, which can be negative for a "backward" duration. It provides accessors methods to create and read the value in various units, as well as impls for many arithmetic operators in std::ops.

let timespan = FloatDuration::hours(2.5) + FloatDuration::seconds(30.0);
assert_eq!(timespan, FloatDuration::seconds(9030.0));
assert_eq!(timespan, FloatDuration::minutes(150.5));

Additionally, a TimePoint trait is provided for computing a FloatDuration between two objects representing a point in time.

Example Usage

Compute the number of blocks in a larger interval:

use float_duration::FloatDuration;

let time_block = FloatDuration::minutes(5.0);
let blocks_per_hour = FloatDuration::hours(1.0) / time_block;

assert_eq!(blocks_per_hour, 12.0);

Perform a basic numerical integration of a mass on a spring:

use float_duration::FloatDuration;

fn acceleration(m: f64, x: f64, t: FloatDuration) -> f64 {
    0.5*m*x*x
}

fn main() {
    let mut sim_time = FloatDuration::zero();
    let end_time = FloatDuration::minutes(2.0);
    let dt = FloatDuration::milliseconds(50.0);

    let mut x = 2.0;
    let mut v = 0.0;
    let m = 1.0;

    while sim_time < end_time {
        let acc = acceleration(m, x, sim_time);
        v += acc*dt.as_seconds();
        x += v*dt.as_seconds();
        sim_time += dt;
    }
}

Run a function on 100 evenly spaced durations:

use float_duration::{FloatDuration, subdivide};

fn compute_value(t: FloatDuration) -> f64 {
    t.as_seconds()*t.as_seconds()
}

for time in subdivide(FloatDuration::zero(), FloatDuration::hours(1.0), 100) {
    println!("{}", compute_value(time));
}

Library Support

Currently float_duration can be compiled without any dependencies, but it provides optional features for interfacing with other libraries.

std::time

The std::time module is supported and FloatDuration can be used directly with SystemTime and Instant:

// TimePoint needed for `float_duration_since`.
use float_duration::{FloatDuration, TimePoint};
use std::time::{Instant, SystemTime};


let start_time = Instant::now();
//Do lengthy operation...
let end_time = Instant::now();

println!("Took {}.", end_time.float_duration_since(start_time).unwrap());

FloatDuration may also be converted to/from std::time::Duration via the to_std and from_std methods.

approx

FloatDuration provides an implementation of approx::ApproxEq for near-equality comparisons of FloatDuration if the approx feature is enabled. Since FloatDuration uses floating point values, this should be the preferred way to establish equality between two duration objects.

chrono

Similar to std::time, computing a FloatDuration between any two of the same type of date or time objects is supported via TimePoint trait impls, assuming the feature "chrono" is enabled. Additionally, FloatDuration objects can be converted to/from chrono::Duration objects via the to_chrono and from_chrono methods.

Note: if the chrono feature is enabled, the time feature must also be enabled as chrono directly relies on some types defined in time.

use chrono::{UTC, TimeZone};
use float_duration::{TimePoint, FloatDuration};

let date1 = UTC.ymd(2017, 5, 25).and_hms(10, 0, 0);
let date2 = UTC.ymd(2017, 5, 26).and_hms(12, 0, 0);

assert_eq!(date2.float_duration_since(date1).unwrap(), FloatDuration::days(1.0) +
    FloatDuration::hours(2.0));

serde

FloatDuration supports serialization with serde. Presently, a FloatDuration is serialized to a single f64 value representing the number of seconds in the duration.

Reexports

pub use duration::FloatDuration;
pub use duration::TimePoint;
pub use duration::FromDuration;
pub use duration::IntoDuration;
pub use error::OutOfRangeError;
pub use iter::subdivide;
pub use iter::subdivide_with_step;

Modules

duration

Floating-point duration type FloatDuration and helpers.

error

Error handling facilities.

iter

Utilities for iteration with duration objects.