#[derive(Debug, Default, Clone, Copy)]
pub struct Clock {
now: u64,
tz_offset_secs: i32,
}
impl Clock {
pub const SECONDS_PER_DAY: i64 = 86400;
#[cfg(test)]
pub fn at(now: u64) -> Self {
Self {
now,
tz_offset_secs: 0,
}
}
pub fn with_offset(now: u64, tz_offset_secs: i32) -> Self {
Self {
now,
tz_offset_secs,
}
}
pub fn now(&self) -> u64 {
self.now
}
pub fn day_id_of(&self, timestamp: u64) -> i64 {
(timestamp as i64 + self.tz_offset_secs as i64) / Self::SECONDS_PER_DAY
}
pub fn today_id(&self) -> i64 {
self.day_id_of(self.now)
}
pub fn day_start(self, day_id: i64) -> u64 {
(Self::SECONDS_PER_DAY * day_id) as u64
}
pub fn today_start(self) -> u64 {
let today_id = (self.now as i64 + self.tz_offset_secs as i64) / Self::SECONDS_PER_DAY;
self.day_start(today_id)
}
pub fn day_of_week(&self) -> i64 {
self.day_id_of(self.now).rem_euclid(7)
}
pub fn local_seconds_since_midnight(&self) -> i64 {
let local_seconds = self.now as i64 + self.tz_offset_secs as i64;
local_seconds.rem_euclid(86400)
}
pub fn from_now() -> Self {
use std::time::{SystemTime, UNIX_EPOCH};
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
let tz_offset_secs = chrono::Local::now().offset().local_minus_utc();
Self::with_offset(now, tz_offset_secs)
}
pub fn tz_offset_secs(&self) -> i32 {
self.tz_offset_secs
}
}