2024-01-21 00:04:09 +00:00
|
|
|
//! System related
|
|
|
|
//!
|
|
|
|
//! Requires `std`.
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------- Use
|
|
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------- Public API
|
|
|
|
#[inline]
|
|
|
|
/// Returns the current system time as a UNIX timestamp.
|
|
|
|
///
|
|
|
|
/// ```rust
|
2024-01-22 02:09:09 +00:00
|
|
|
/// # use cuprate_helper::time::*;
|
2024-01-21 00:04:09 +00:00
|
|
|
/// assert!(current_unix_timestamp() > 0);
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// # Panics
|
|
|
|
/// This function panics if the call to get the system time fails.
|
|
|
|
pub fn current_unix_timestamp() -> u64 {
|
|
|
|
SystemTime::now()
|
|
|
|
.duration_since(UNIX_EPOCH)
|
|
|
|
.unwrap()
|
|
|
|
.as_secs()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
/// Get the clock time of a UNIX timestamp
|
|
|
|
///
|
|
|
|
/// The input must be a UNIX timestamp.
|
|
|
|
///
|
|
|
|
/// The returned `u64` will represent how many seconds has
|
|
|
|
/// passed on the day corresponding to that timestamp.
|
|
|
|
///
|
|
|
|
/// The output is guaranteed to be in the range of `0..=86399`.
|
|
|
|
///
|
|
|
|
/// ```rust
|
2024-01-22 02:09:09 +00:00
|
|
|
/// # use cuprate_helper::time::*;
|
2024-01-21 00:04:09 +00:00
|
|
|
/// // October 20th 2023 - 10:18:30 PM
|
|
|
|
/// const TIME: u64 = 1697840310;
|
|
|
|
///
|
|
|
|
/// let seconds = unix_clock(TIME);
|
|
|
|
/// assert_eq!(seconds, 80310);
|
|
|
|
///
|
|
|
|
/// let (h, m, s) = secs_to_clock(seconds);
|
|
|
|
/// // 10:18:30 PM.
|
|
|
|
/// assert_eq!((h, m, s), (22, 18, 30))
|
|
|
|
/// ```
|
|
|
|
pub const fn unix_clock(seconds_after_unix_epoch: u64) -> u32 {
|
|
|
|
(seconds_after_unix_epoch % 86400) as _
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
/// Convert seconds to `hours`, `minutes` and `seconds`.
|
|
|
|
///
|
|
|
|
/// - The seconds returned is guaranteed to be `0..=59`
|
|
|
|
/// - The minutes returned is guaranteed to be `0..=59`
|
|
|
|
/// - The hours returned can be over `23`, as this is not a clock function,
|
2024-07-25 21:47:39 +00:00
|
|
|
/// see [`secs_to_clock`] for clock-like behavior that wraps around on `24`
|
2024-01-21 00:04:09 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
2024-01-22 02:09:09 +00:00
|
|
|
/// # use cuprate_helper::time::*;
|
2024-01-21 00:04:09 +00:00
|
|
|
/// // 59 seconds.
|
|
|
|
/// assert_eq!(secs_to_hms(59), (0, 0, 59));
|
|
|
|
///
|
|
|
|
/// // 1 minute.
|
|
|
|
/// assert_eq!(secs_to_hms(60), (0, 1, 0));
|
|
|
|
///
|
|
|
|
/// // 59 minutes, 59 seconds.
|
|
|
|
/// assert_eq!(secs_to_hms(3599), (0, 59, 59));
|
|
|
|
///
|
|
|
|
/// // 1 hour.
|
|
|
|
/// assert_eq!(secs_to_hms(3600), (1, 0, 0));
|
|
|
|
///
|
|
|
|
/// // 23 hours, 59 minutes, 59 seconds.
|
|
|
|
/// assert_eq!(secs_to_hms(86399), (23, 59, 59));
|
|
|
|
///
|
|
|
|
/// // 24 hours.
|
|
|
|
/// assert_eq!(secs_to_hms(86400), (24, 0, 0));
|
|
|
|
/// ```
|
|
|
|
pub const fn secs_to_hms(seconds: u64) -> (u64, u8, u8) {
|
|
|
|
let hours = seconds / 3600;
|
|
|
|
let minutes = (seconds % 3600) / 60;
|
|
|
|
let seconds = (seconds % 3600) % 60;
|
|
|
|
|
|
|
|
debug_assert!(minutes < 60);
|
|
|
|
debug_assert!(seconds < 60);
|
|
|
|
|
|
|
|
(hours, minutes as u8, seconds as u8)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
/// Convert seconds to clock time, `hours`, `minutes` and `seconds`.
|
|
|
|
///
|
|
|
|
/// This is the same as [`secs_to_hms`] except it will wrap around,
|
|
|
|
/// e.g, `24:00:00` would turn into `00:00:00`.
|
|
|
|
///
|
|
|
|
/// - The seconds returned is guaranteed to be `0..=59`
|
|
|
|
/// - The minutes returned is guaranteed to be `0..=59`
|
|
|
|
/// - The hours returned is guaranteed to be `0..=23`
|
|
|
|
///
|
|
|
|
/// ```rust
|
2024-01-22 02:09:09 +00:00
|
|
|
/// # use cuprate_helper::time::*;
|
2024-01-21 00:04:09 +00:00
|
|
|
/// // 59 seconds.
|
|
|
|
/// assert_eq!(secs_to_clock(59), (0, 0, 59));
|
|
|
|
///
|
|
|
|
/// // 1 minute.
|
|
|
|
/// assert_eq!(secs_to_clock(60), (0, 1, 0));
|
|
|
|
///
|
|
|
|
/// // 59 minutes, 59 seconds.
|
|
|
|
/// assert_eq!(secs_to_clock(3599), (0, 59, 59));
|
|
|
|
///
|
|
|
|
/// // 1 hour.
|
|
|
|
/// assert_eq!(secs_to_clock(3600), (1, 0, 0));
|
|
|
|
///
|
|
|
|
/// // 23 hours, 59 minutes, 59 seconds.
|
|
|
|
/// assert_eq!(secs_to_clock(86399), (23, 59, 59));
|
|
|
|
///
|
|
|
|
/// // 24 hours (wraps back)
|
|
|
|
/// assert_eq!(secs_to_clock(86400), (0, 0, 0));
|
|
|
|
///
|
|
|
|
/// // 24 hours, 59 minutes, 59 seconds (wraps back)
|
|
|
|
/// assert_eq!(secs_to_clock(89999), (0, 59, 59));
|
|
|
|
/// ```
|
|
|
|
pub const fn secs_to_clock(seconds: u32) -> (u8, u8, u8) {
|
|
|
|
let seconds = seconds % 86400;
|
|
|
|
let (h, m, s) = secs_to_hms(seconds as u64);
|
|
|
|
|
|
|
|
debug_assert!(h < 24);
|
|
|
|
debug_assert!(m < 60);
|
|
|
|
debug_assert!(s < 60);
|
|
|
|
|
|
|
|
(h as u8, m, s)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
/// Get the current system time in the system's timezone
|
|
|
|
///
|
|
|
|
/// The returned value is the total amount of seconds passed in the current day.
|
|
|
|
///
|
|
|
|
/// This is guaranteed to return a value between `0..=86399`
|
|
|
|
///
|
|
|
|
/// This will return `0` if the underlying system call fails.
|
|
|
|
pub fn time() -> u32 {
|
|
|
|
use chrono::Timelike;
|
|
|
|
let now = chrono::offset::Local::now().time();
|
|
|
|
(now.hour() * 3600) + (now.minute() * 60) + now.second()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
/// Get the current system time in the UTC timezone
|
|
|
|
///
|
|
|
|
/// The returned value is the total amount of seconds passed in the current day.
|
|
|
|
///
|
|
|
|
/// This is guaranteed to return a value between `0..=86399`
|
|
|
|
pub fn time_utc() -> u32 {
|
|
|
|
unix_clock(chrono::offset::Local::now().timestamp() as u64)
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------- Tests
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {}
|