#[cfg(unix)]
mod unix;
mod instant;
#[cfg(windows)]
mod windows;
use std::time::Duration;
#[cfg(unix)]
use unix as _impl;
#[cfg(windows)]
use windows as _impl;
use time::{Month, OffsetDateTime, UtcOffset};
mod sealed {
use std::time::Duration;
use time::{Month, OffsetDateTime, UtcOffset};
pub trait SealUO {}
pub trait SealODT {}
pub trait SealM {}
pub trait SealD {}
impl SealUO for UtcOffset {}
impl SealODT for OffsetDateTime {}
impl SealM for Month {}
impl SealD for Duration {}
}
pub trait MonthExt: sealed::SealM {
fn from_index(index: u8) -> Option<Month>;
}
impl MonthExt for Month {
fn from_index(index: u8) -> Option<Month> {
match index {
1 => Some(Month::January),
2 => Some(Month::February),
3 => Some(Month::March),
4 => Some(Month::April),
5 => Some(Month::May),
6 => Some(Month::June),
7 => Some(Month::July),
8 => Some(Month::August),
9 => Some(Month::September),
10 => Some(Month::October),
11 => Some(Month::November),
12 => Some(Month::December),
_ => None,
}
}
}
pub trait LocalUtcOffset: sealed::SealUO {
fn current_local_offset() -> Option<UtcOffset>;
fn local_offset_at(datetime: OffsetDateTime) -> Option<UtcOffset>;
}
pub trait LocalOffsetDateTime: sealed::SealODT {
fn now_local() -> Option<OffsetDateTime>;
}
impl LocalUtcOffset for UtcOffset {
#[inline]
fn current_local_offset() -> Option<UtcOffset> {
_impl::local_offset_at(&OffsetDateTime::now_utc())
}
#[inline]
fn local_offset_at(datetime: OffsetDateTime) -> Option<UtcOffset> {
_impl::local_offset_at(&datetime)
}
}
impl LocalOffsetDateTime for OffsetDateTime {
fn now_local() -> Option<OffsetDateTime> {
let tm = OffsetDateTime::now_utc();
let offset = _impl::local_offset_at(&tm)?;
Some(tm.to_offset(offset))
}
}
pub trait DurationNewUnchecked: sealed::SealD {
unsafe fn new_unchecked(secs: u64, subsec_nanos: u32) -> Duration;
}
impl DurationNewUnchecked for Duration {
unsafe fn new_unchecked(secs: u64, subsec_nanos: u32) -> Duration {
const NANOS_PER_SEC: u32 = 1000000000;
if subsec_nanos >= NANOS_PER_SEC {
unsafe { std::hint::unreachable_unchecked() }
}
Duration::new(secs, subsec_nanos)
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct Instant(instant::Instant);
impl Instant {
#[inline(always)]
pub fn now() -> Self {
Self(instant::Instant::now())
}
#[inline(always)]
pub fn elapsed(&self) -> Duration {
self.0.elapsed()
}
}
#[cfg(test)]
mod tests {
use time::{OffsetDateTime, UtcOffset};
use crate::time::{Instant, LocalUtcOffset};
use super::LocalOffsetDateTime;
#[test]
fn current_offset() {
let offset = UtcOffset::current_local_offset();
println!("Offset: {:?}", offset)
}
#[test]
fn now_local() {
let date = OffsetDateTime::now_local();
println!("Date: {:?}", date)
}
#[test]
fn instant() {
let time = Instant::now();
std::thread::sleep(std::time::Duration::from_millis(8));
let elapsed = time.elapsed();
println!("{:?}", elapsed);
assert!(elapsed >= std::time::Duration::from_millis(8));
}
}