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};