use candid::CandidType;
use serde::{Deserialize, Serialize};
#[cfg(test)]
use crate::mocks::time_mock as ic_timestamp;
#[cfg(not(test))]
use ic_cdk::api::time as ic_timestamp;
#[derive(CandidType, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
pub struct NanoTimeStamp(pub u64);
impl NanoTimeStamp {
pub const NS_PER_SECOND: u64 = 1_000_000_000;
pub const NS_PER_MINUTE: u64 = Self::NS_PER_SECOND * 60;
pub const NS_PER_HOUR: u64 = Self::NS_PER_MINUTE * 60;
pub const NS_PER_DAY: u64 = Self::NS_PER_HOUR * 24;
pub fn now() -> Self {
NanoTimeStamp(ic_timestamp())
}
pub fn days_from_now(days: u64) -> Self {
let ns_to_add = days * Self::NS_PER_DAY;
NanoTimeStamp(ic_timestamp() + ns_to_add)
}
pub fn to_secs(&self) -> u64 {
self.0 / Self::NS_PER_SECOND
}
pub fn to_millis(&self) -> u64 {
self.0 / 1_000_000
}
pub fn has_passed(&self) -> bool {
let now = NanoTimeStamp::now();
self < &now
}
pub fn is_future(&self) -> bool {
let now = NanoTimeStamp::now();
self > &now
}
pub fn time_until(&self) -> u64 {
let now = NanoTimeStamp::now();
if self > &now {
self.0 - now.0
} else {
0
}
}
pub fn time_since(&self) -> u64 {
let now = NanoTimeStamp::now();
if self < &now {
now.0 - self.0
} else {
0
}
}
pub fn rate_limit_exceeded(&self, rate_limit: u64) -> bool {
let now = NanoTimeStamp::now();
let time_since = now.0 - self.0;
time_since < rate_limit
}
pub fn add_secs(&self, secs: u64) -> Self {
let ns_to_add = secs * Self::NS_PER_SECOND;
NanoTimeStamp(self.0 + ns_to_add)
}
pub fn add_mins(&self, mins: u64) -> Self {
let ns_to_add = mins * Self::NS_PER_MINUTE;
NanoTimeStamp(self.0 + ns_to_add)
}
pub fn add_hours(&self, hours: u64) -> Self {
let ns_to_add = hours * Self::NS_PER_HOUR;
NanoTimeStamp(self.0 + ns_to_add)
}
pub fn add_days(&self, days: u64) -> Self {
let ns_to_add = days * Self::NS_PER_DAY;
NanoTimeStamp(self.0 + ns_to_add)
}
pub fn get_secs(&self) -> u64 {
self.0 / Self::NS_PER_SECOND
}
pub fn get_mins(&self) -> u64 {
self.0 / Self::NS_PER_MINUTE
}
pub fn get_hours(&self) -> u64 {
self.0 / Self::NS_PER_HOUR
}
pub fn get_days(&self) -> u64 {
self.0 / Self::NS_PER_DAY
}
}