use crate::date::Date;
use crate::datetime::DateTime;
use crate::duration::Duration;
use crate::time::Time;
use std::time::{Instant, SystemTime, UNIX_EPOCH};
pub trait Clock {
fn now(&self) -> DateTime;
fn today(&self) -> Date;
fn time_now(&self) -> Time;
}
pub struct SystemClock;
impl Clock for SystemClock {
fn now(&self) -> DateTime {
let elapsed = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or(std::time::Duration::ZERO);
DateTime::from_unix_millis(elapsed.as_millis() as i64)
}
fn today(&self) -> Date {
self.now().date
}
fn time_now(&self) -> Time {
self.now().time
}
}
pub struct MonotonicClock {
start: Instant,
}
impl MonotonicClock {
pub fn new() -> Self {
MonotonicClock {
start: Instant::now(),
}
}
pub fn start() -> Self {
MonotonicClock::new()
}
pub fn elapsed(&self) -> Duration {
let elapsed = self.start.elapsed();
Duration {
secs: elapsed.as_secs() as i64,
nanos: elapsed.subsec_nanos() as i32,
}
}
pub fn reset(&mut self) {
self.start = Instant::now();
}
}
impl DateTime {
pub fn now() -> Self {
SystemClock.now()
}
}
impl Date {
pub fn today() -> Self {
SystemClock.today()
}
}
impl Time {
pub fn now() -> Self {
SystemClock.time_now()
}
}