omf/
date_time.rs

1//! Utility functions for date and date-time conversion.
2
3use chrono::{DateTime, Duration, NaiveDate, Utc};
4
5/// Convert a date to the number of days since the epoch.
6pub fn date_to_f64(date: NaiveDate) -> f64 {
7    date_to_i64(date) as f64
8}
9
10/// Convert a date-time the number of seconds since the epoch, including fractional seconds,
11/// at a bit less than microsecond precision.
12pub fn date_time_to_f64(date_time: DateTime<Utc>) -> f64 {
13    const MICRO: i64 = 1_000_000;
14    let us = date_time_to_i64(date_time);
15    let s = us / MICRO;
16    let f = us % MICRO;
17    (s as f64) + (f as f64) / (MICRO as f64)
18}
19
20/// Convert a date to the number of days since the epoch.
21pub fn date_to_i64(date: NaiveDate) -> i64 {
22    date.signed_duration_since(NaiveDate::default()).num_days()
23}
24
25/// Convert a date-time to the number of microseconds since the epoch.
26pub fn date_time_to_i64(date_time: DateTime<Utc>) -> i64 {
27    date_time.timestamp_micros()
28}
29
30/// Convert a number of days since the epoch back to a date.
31pub fn i64_to_date(value: i64) -> NaiveDate {
32    Duration::try_days(value)
33        .and_then(|d| NaiveDate::default().checked_add_signed(d))
34        .unwrap_or(if value < 0 {
35            NaiveDate::MIN
36        } else {
37            NaiveDate::MAX
38        })
39}
40
41/// Convert a number of microseconds since the epoch back to a date.
42pub fn i64_to_date_time(value: i64) -> DateTime<Utc> {
43    DateTime::<Utc>::default()
44        .checked_add_signed(Duration::microseconds(value))
45        .unwrap_or(if value < 0 {
46            DateTime::<Utc>::MIN_UTC
47        } else {
48            DateTime::<Utc>::MAX_UTC
49        })
50}
51
52/// Convert a number of milliseconds since the epoch back to a date.
53pub fn i64_milli_to_date_time(value: i64) -> DateTime<Utc> {
54    Duration::try_milliseconds(value)
55        .and_then(|d| DateTime::<Utc>::default().checked_add_signed(d))
56        .unwrap_or(if value < 0 {
57            DateTime::<Utc>::MIN_UTC
58        } else {
59            DateTime::<Utc>::MAX_UTC
60        })
61}
62
63/// Convert a number of nanoseconds since the epoch back to a date.
64pub fn i64_nano_to_date_time(value: i64) -> DateTime<Utc> {
65    DateTime::<Utc>::default()
66        .checked_add_signed(Duration::nanoseconds(value))
67        .unwrap_or(if value < 0 {
68            DateTime::<Utc>::MIN_UTC
69        } else {
70            DateTime::<Utc>::MAX_UTC
71        })
72}
73
74/// Returns the current date and time in UTC.
75pub fn utc_now() -> DateTime<Utc> {
76    chrono::Utc::now()
77}