1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
//! Temporal quantification using floating-point quantities. //! //! This crate provides quantification for spans of time. Unlike the standard //! [`std::time`](https://doc.rust-lang.org/std/time/index.html) or the //! [chrono](https://crates.io/crates/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`: //! //! ```ignore //! [dependencies] //! float_duration = "0.3.3" //! ``` //! # Overview //! //! This crate provides a single primary type: //! [`FloatDuration`](duration/struct.FloatDuration.html) 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 `impl`s for many //! arithmetic operators in `std::ops`. //! //! ```rust //! # use float_duration::*; //! 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`](duration/trait.TimePoint.html) 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: //! //! ```rust //! 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: //! //! ```rust //! 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: //! //! ```rust //! 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`: //! //! ```rust //! // 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](https://crates.io/crates/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](https://crates.io/crates/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`. //! //! ```rust,ignore //! 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](https://crates.io/crates/serde) //! //! `FloatDuration` supports serialization with `serde`. Presently, a `FloatDuration` //! is serialized to a single `f64` value representing the number of seconds in the //! duration. #[cfg(feature = "chrono")] extern crate chrono; #[cfg(feature = "time")] extern crate time; #[cfg(feature = "approx")] extern crate approx; #[cfg(feature = "serde")] extern crate serde; #[cfg(all(test, feature = "serde"))] extern crate serde_test; pub mod duration; pub mod error; pub mod iter; pub use duration::{FloatDuration, TimePoint, FromDuration, IntoDuration}; pub use error::OutOfRangeError; pub use iter::{subdivide, subdivide_with_step};