#![cfg_attr(not(feature="std"), no_std)]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
use chrono::*;
const HOUR_TO_SEC: i32 = 3600;
const MIN_TO_SEC: i32 = 60;
pub mod known_timezones;
#[cfg(feature = "serde")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
pub mod serde;
#[derive(Clone, Copy, Eq, PartialEq, Hash, Default, Ord, PartialOrd)]
pub struct TimeZoneZst<const HOUR: i32, const MINUTE: u32>;
#[deprecated(since="0.2.0", note = "Use `TimeZoneZst` instead.")]
pub type UtcZst<const HOUR: i32, const MINUTE: u32> = TimeZoneZst<HOUR, MINUTE>;
impl<const HOUR: i32, const MINUTE: u32> TimeZoneZst<HOUR, MINUTE> {
pub const OFFSET_SECS: i32 =
HOUR * HOUR_TO_SEC + if HOUR < 0 { -1 } else { 1 } * (MINUTE as i32) * MIN_TO_SEC;
pub const IS_IN_VALID_RANGE: bool = (HOUR >= -23) & (HOUR <= 23) & (MINUTE < 60);
pub const FIXED_OFFSET: FixedOffset = match (FixedOffset::east_opt(Self::OFFSET_SECS), Self::IS_IN_VALID_RANGE) {
(Some(fix), true) => fix,
_ => panic!("Invalid TimeZone"),
};
pub const fn new() -> Self {
TimeZoneZst
}
#[cfg(clock)]
pub fn today() -> Date<Self> {
Utc::today().with_timezone(Self::new())
}
#[cfg(clock)]
pub fn now() -> DateTime<Self> {
Utc::now().with_timezone(Self::new())
}
}
impl<const HOUR: i32, const MINUTE: u32> Offset for TimeZoneZst<HOUR, MINUTE> {
fn fix(&self) -> FixedOffset {
Self::FIXED_OFFSET
}
}
impl<const HOUR: i32, const MINUTE: u32> TimeZone for TimeZoneZst<HOUR, MINUTE> {
type Offset = Self;
fn from_offset(offset: &Self::Offset) -> Self {
*offset
}
fn offset_from_local_date(&self, _local: &NaiveDate) -> LocalResult<Self::Offset> {
LocalResult::Single(*self)
}
fn offset_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<Self::Offset> {
LocalResult::Single(*self)
}
fn offset_from_utc_date(&self, _utc: &NaiveDate) -> Self::Offset {
*self
}
fn offset_from_utc_datetime(&self, _utc: &NaiveDateTime) -> Self::Offset {
*self
}
}
impl<const HOUR: i32, const MINUTE: u32> core::fmt::Debug for TimeZoneZst<HOUR, MINUTE> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "{:+03}:{:02}", HOUR, MINUTE)
}
}
impl<const HOUR: i32, const MINUTE: u32> core::fmt::Display for TimeZoneZst<HOUR, MINUTE> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "{:+03}:{:02}", HOUR, MINUTE)
}
}
#[cfg(test)]
#[cfg(feature="std")]
mod tests {
use crate::known_timezones::*;
use crate::*;
#[test]
fn display() {
let p9 = UtcP9::default();
assert_eq!(&p9.to_string(), "+09:00");
assert_eq!(std::mem::size_of_val(&p9), 0);
assert_eq!(UtcP9::IS_IN_VALID_RANGE, true);
let n = p9.with_ymd_and_hms(2000, 1, 1,12, 00, 00).unwrap();
assert_eq!(
n.naive_utc(),
NaiveDate::from_ymd_opt(2000, 1, 1).unwrap().and_hms_opt(3, 0, 0).unwrap()
);
let m9 = UtcM9::default();
assert_eq!(&m9.to_string(), "-09:00");
let n = m9.with_ymd_and_hms(2000, 1, 1,12, 00, 00).unwrap();
assert_eq!(
n.naive_utc(),
NaiveDate::from_ymd_opt(2000, 1, 1).unwrap().and_hms_opt(21, 0, 0).unwrap()
);
let p9 = UtcP9_30::default();
let n = p9.with_ymd_and_hms(2000, 1, 1,12, 00, 00).unwrap();
assert_eq!(
n.naive_utc(),
NaiveDate::from_ymd_opt(2000, 1, 1).unwrap().and_hms_opt(2, 30, 0).unwrap()
);
let m9 = UtcM9_30::default();
let n = m9.with_ymd_and_hms(2000, 1, 1,12, 00, 00).unwrap();
assert_eq!(
n.naive_utc(),
NaiveDate::from_ymd_opt(2000, 1, 1).unwrap().and_hms_opt(21, 30, 0).unwrap()
);
}
}