nstd_sys/
time.rs

1//! Time utilities.
2use crate::{
3    core::time::{nstd_core_time_duration_new, NSTDDuration},
4    NSTDFloat64, NSTDInt64, NSTDUInt32,
5};
6use cfg_if::cfg_if;
7use nstdapi::nstdapi;
8use std::time::{SystemTime, UNIX_EPOCH};
9
10cfg_if! {
11    if #[cfg(unix)] {
12        use crate::os::unix::time::{
13            nstd_os_unix_time_add, nstd_os_unix_time_get, nstd_os_unix_time_nanoseconds,
14            nstd_os_unix_time_now, nstd_os_unix_time_seconds, nstd_os_unix_time_sub,
15            NSTDUnixOptionalTime, NSTDUnixTime,
16        };
17
18        /// A structure representing system time since January 1st 1970.
19        pub type NSTDTime = NSTDUnixTime;
20        impl From<SystemTime> for NSTDTime {
21            /// Converts a [`SystemTime`] into an [`NSTDTime`] object.
22            fn from(value: SystemTime) -> Self {
23                match value.duration_since(UNIX_EPOCH) {
24                    Ok(dur) => Self::from_duration(
25                        #[allow(unused_unsafe)]
26                        // SAFETY: This operation is safe.
27                        unsafe { nstd_core_time_duration_new(dur.as_secs_f64()) },
28                    ),
29                    Err(dur) => Self::from_duration(
30                        #[allow(unused_unsafe)]
31                        // SAFETY: This operation is safe.
32                        unsafe { nstd_core_time_duration_new(-dur.duration().as_secs_f64()) },
33                    ),
34                }
35            }
36        }
37
38        /// Represents an optional value of type `NSTDTime`.
39        pub type NSTDOptionalTime = NSTDUnixOptionalTime;
40    } else {
41        use crate::core::{
42            optional::{gen_optional, NSTDOptional},
43            time::{
44                nstd_core_time_duration_get, nstd_core_time_duration_nanoseconds,
45                nstd_core_time_duration_seconds,
46            },
47        };
48
49        /// A structure representing system time since January 1st 1970.
50        #[nstdapi]
51        #[derive(Clone, Copy, PartialEq)]
52        pub struct NSTDTime {
53            /// The time span since January 1st 1970.
54            duration: NSTDDuration,
55        }
56        impl From<SystemTime> for NSTDTime {
57            /// Converts a [`SystemTime`] into an [`NSTDTime`] object.
58            fn from(value: SystemTime) -> Self {
59                match value.duration_since(UNIX_EPOCH) {
60                    #[allow(unused_unsafe)]
61                    Ok(dur) => Self {
62                        // SAFETY: This operation is safe.
63                        duration: unsafe {
64                            nstd_core_time_duration_new(dur.as_secs_f64())
65                        },
66                    },
67                    #[allow(unused_unsafe)]
68                    Err(dur) => Self {
69                        // SAFETY: This operation is safe.
70                        duration: unsafe {
71                            nstd_core_time_duration_new(-dur.duration().as_secs_f64())
72                        },
73                    },
74                }
75            }
76        }
77        gen_optional!(NSTDOptionalTime, NSTDTime);
78    }
79}
80
81/// Returns the current system time as an `NSTDTime` object.
82///
83/// # Returns
84///
85/// `NSTDOptionalTime time` - The current time on success, or an uninitialized "none" variant on
86/// failure.
87#[inline]
88#[nstdapi]
89pub fn nstd_time_now() -> NSTDOptionalTime {
90    #[cfg(unix)]
91    return nstd_os_unix_time_now();
92    #[cfg(not(unix))]
93    return NSTDOptional::Some(NSTDTime::from(SystemTime::now()));
94}
95
96/// Returns the number of seconds stored in an `NSTDTime` object as an `NSTDFloat64`.
97///
98/// # Parameters:
99///
100/// - `NSTDTime time` - The time object.
101///
102/// # Returns
103///
104/// `NSTDFloat64 seconds` - The number of seconds in a time object represented as an
105/// `NSTDFloat64`.
106#[inline]
107#[nstdapi]
108pub const fn nstd_time_get(time: NSTDTime) -> NSTDFloat64 {
109    #[cfg(unix)]
110    return nstd_os_unix_time_get(time);
111    #[cfg(not(unix))]
112    return nstd_core_time_duration_get(time.duration);
113}
114
115/// Returns the number of seconds in an `NSTDTime` object.
116///
117/// # Parameters:
118///
119/// - `NSTDTime time` - The time object.
120///
121/// # Returns
122///
123/// `NSTDInt64 seconds` - The number of seconds held in `time`.
124#[inline]
125#[nstdapi]
126pub const fn nstd_time_seconds(time: NSTDTime) -> NSTDInt64 {
127    #[cfg(unix)]
128    return nstd_os_unix_time_seconds(time);
129    #[cfg(not(unix))]
130    return nstd_core_time_duration_seconds(time.duration);
131}
132
133/// Returns the number of nanoseconds in an `NSTDTime` object.
134///
135/// # Parameters:
136///
137/// - `NSTDTime time` - The time object.
138///
139/// # Returns
140///
141/// `NSTDUInt32 nanoseconds` - The number of nanoseconds held in `time`.
142#[inline]
143#[nstdapi]
144pub fn nstd_time_nanoseconds(time: NSTDTime) -> NSTDUInt32 {
145    #[cfg(unix)]
146    return nstd_os_unix_time_nanoseconds(time);
147    #[cfg(not(unix))]
148    return nstd_core_time_duration_nanoseconds(time.duration);
149}
150
151/// Computes the addition of an `NSTDTime` object and an `NSTDDuration`.
152///
153/// # Parameters:
154///
155/// - `NSTDTime time` - The time object
156///
157/// - `NSTDDuration duration` - The duration to add.
158///
159/// # Returns
160///
161/// `NSTDTime time` - The result of the addition.
162#[inline]
163#[nstdapi]
164pub fn nstd_time_add(time: NSTDTime, duration: NSTDDuration) -> NSTDTime {
165    #[cfg(unix)]
166    return nstd_os_unix_time_add(time, duration);
167    #[cfg(not(unix))]
168    {
169        let s = nstd_core_time_duration_get(time.duration) + nstd_core_time_duration_get(duration);
170        NSTDTime {
171            duration: nstd_core_time_duration_new(s),
172        }
173    }
174}
175
176/// Computes the subtraction between an `NSTDTime` object and an `NSTDDuration`.
177///
178/// # Parameters:
179///
180/// - `NSTDTime time` - The time object
181///
182/// - `NSTDDuration duration` - The duration to subtract.
183///
184/// # Returns
185///
186/// `NSTDTime time` - The result of the subtraction.
187#[inline]
188#[nstdapi]
189pub fn nstd_time_sub(time: NSTDTime, duration: NSTDDuration) -> NSTDTime {
190    #[cfg(unix)]
191    return nstd_os_unix_time_sub(time, duration);
192    #[cfg(not(unix))]
193    {
194        let s = nstd_core_time_duration_get(time.duration) - nstd_core_time_duration_get(duration);
195        NSTDTime {
196            duration: nstd_core_time_duration_new(s),
197        }
198    }
199}