use std::time::{Duration, SystemTime};
#[derive(
Clone,
Copy,
serde::Serialize,
serde::Deserialize,
Debug,
derive_more::From,
derive_more::Mul,
derive_more::Div,
derive_more::MulAssign,
derive_more::DivAssign,
PartialEq,
Eq,
PartialOrd,
Ord,
derive_more::Add,
derive_more::Sub,
derive_more::AddAssign,
derive_more::SubAssign,
Hash,
bytemuck::Pod,
bytemuck::Zeroable,
)]
#[repr(C)]
#[serde(transparent)]
#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct TimestampSec(pub u32);
#[derive(
Clone,
Copy,
serde::Serialize,
serde::Deserialize,
Debug,
derive_more::From,
derive_more::Mul,
derive_more::Div,
derive_more::MulAssign,
derive_more::DivAssign,
PartialEq,
Eq,
PartialOrd,
Ord,
derive_more::Add,
derive_more::Sub,
derive_more::AddAssign,
derive_more::SubAssign,
Hash,
bytemuck::Pod,
bytemuck::Zeroable,
)]
#[repr(C)]
#[serde(transparent)]
#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct TimestampMs(pub u64);
#[derive(
Clone,
Copy,
serde::Serialize,
serde::Deserialize,
Debug,
derive_more::From,
derive_more::Mul,
derive_more::Div,
derive_more::MulAssign,
derive_more::DivAssign,
PartialEq,
Eq,
PartialOrd,
Ord,
derive_more::Add,
derive_more::Sub,
derive_more::AddAssign,
derive_more::SubAssign,
Hash,
bytemuck::Pod,
bytemuck::Zeroable,
)]
#[repr(C)]
#[serde(transparent)]
#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct TimestampMicros(pub u64);
impl TimestampSec {
pub const ZERO: Self = Self(0);
pub const ONE_SEC: Self = Self(1);
pub const ONE_MINUTE: Self = Self(60);
pub const ONE_HOUR: Self = Self(60 * 60);
pub const ONE_DAY: Self = Self(60 * 60 * 24);
pub const MAX: Self = Self(u32::MAX);
pub fn now() -> Self {
Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as u32)
}
pub const fn sec(&self) -> u32 {
self.0
}
pub const fn ms(&self) -> u64 {
self.sec() as u64 * 1000
}
pub fn elapsed(&self) -> Option<Self> {
Self::now().0.checked_sub(self.0).map(Self)
}
}
impl TimestampMs {
pub const ZERO: Self = Self(0);
pub const ONE_MS: Self = Self(1);
pub const ONE_SEC: Self = Self(1000);
pub const ONE_MINUTE: Self = Self(1000 * 60);
pub const ONE_HOUR: Self = Self(1000 * 60 * 60);
pub const ONE_DAY: Self = Self(1000 * 60 * 60 * 24);
pub const MAX: Self = Self(u64::MAX);
pub fn now() -> Self {
Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as u64)
}
pub const fn sec(&self) -> u32 {
(self.ms() / 1000) as u32
}
pub const fn ms(&self) -> u64 {
self.0
}
pub fn elapsed(&self) -> Option<Self> {
Self::now().0.checked_sub(self.0).map(Self)
}
}
impl TimestampMicros {
pub const ZERO: Self = Self(0);
pub const ONE_MICROS: Self = Self(1);
pub const ONE_MS: Self = Self(1000);
pub const ONE_SEC: Self = Self(1000 * 1000);
pub const ONE_MINUTE: Self = Self(1000 * 1000 * 60);
pub const ONE_HOUR: Self = Self(1000 * 1000 * 60 * 60);
pub const ONE_DAY: Self = Self(1000 * 1000 * 60 * 60 * 24);
pub const MAX: Self = Self(u64::MAX);
pub fn now() -> Self {
Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_micros() as u64)
}
pub const fn sec(&self) -> u32 {
(self.ms() / 1000) as u32
}
pub const fn ms(&self) -> u64 {
self.0 / 1000
}
pub const fn micros(&self) -> u64 {
self.0
}
pub fn elapsed(&self) -> Option<Self> {
Self::now().0.checked_sub(self.0).map(Self)
}
}
impl From<SystemTime> for TimestampMs {
fn from(value: SystemTime) -> Self {
Self(value.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as u64)
}
}
impl From<SystemTime> for TimestampSec {
fn from(value: SystemTime) -> Self {
Self(value.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as u32)
}
}
impl From<SystemTime> for TimestampMicros {
fn from(value: SystemTime) -> Self {
Self(value.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_micros() as u64)
}
}
impl From<TimestampMs> for SystemTime {
fn from(value: TimestampMs) -> Self {
SystemTime::UNIX_EPOCH + Duration::from_millis(value.0)
}
}
impl From<TimestampSec> for SystemTime {
fn from(value: TimestampSec) -> Self {
SystemTime::UNIX_EPOCH + Duration::from_secs(value.0 as u64)
}
}
impl From<TimestampMicros> for SystemTime {
fn from(value: TimestampMicros) -> Self {
SystemTime::UNIX_EPOCH + Duration::from_micros(value.0)
}
}
pub mod ts_sec_str {
use serde::{Deserialize, Serialize};
use super::TimestampSec;
pub fn serialize<S: serde::Serializer>(ts: &TimestampSec, ser: S) -> Result<S::Ok, S::Error> {
ts.0.to_string().serialize(ser)
}
pub fn deserialize<'de, D: serde::Deserializer<'de>>(de: D) -> Result<TimestampSec, D::Error> {
String::deserialize(de)?
.parse::<u32>()
.map(TimestampSec)
.map_err(|_| serde::de::Error::custom("invalid timestamp sec num"))
}
}
pub mod ts_ms_str {
use serde::{Deserialize, Serialize};
use super::TimestampMs;
pub fn serialize<S: serde::Serializer>(ts: &TimestampMs, ser: S) -> Result<S::Ok, S::Error> {
ts.0.to_string().serialize(ser)
}
pub fn deserialize<'de, D: serde::Deserializer<'de>>(de: D) -> Result<TimestampMs, D::Error> {
String::deserialize(de)?
.parse::<u64>()
.map(TimestampMs)
.map_err(|_| serde::de::Error::custom("invalid timestamp ms num"))
}
}
pub mod ts_micros_str {
use serde::{Deserialize, Serialize};
use super::TimestampMicros;
pub fn serialize<S: serde::Serializer>(ts: &TimestampMicros, ser: S) -> Result<S::Ok, S::Error> {
ts.0.to_string().serialize(ser)
}
pub fn deserialize<'de, D: serde::Deserializer<'de>>(de: D) -> Result<TimestampMicros, D::Error> {
String::deserialize(de)?
.parse::<u64>()
.map(TimestampMicros)
.map_err(|_| serde::de::Error::custom("invalid timestamp micros num"))
}
}