pub use crate::types::data::date::{Date};
use crate::types::{
data::{
time::{Time},
zone::{Sign, Zone}
},
planets::{
earth::{
calendar::{
view::{CalendarView},
constants::{
months::{Months},
}
}
},
},
};
#[cfg(any(
feature = "platform_specific_functions_darwin",
feature = "platform_specific_functions_unix",
feature = "platform_specific_functions_windows"
))]
use crate::{
platform::{
tz::{local_timezone}
}
};
impl Date {
pub fn utc(view: CalendarView) -> Date {
return Self::of(
view,
Time::unix().as_secs() as u128,
Zone {
sign: Sign::Unsigned,
hours: 0, minutes: 0,
seconds: 0
},
true
);
}
pub fn now(view: CalendarView, time_zone: Zone) -> Date {
return Self::of(view, Time::unix().as_secs() as u128, time_zone, false);
}
#[cfg(any(
feature = "platform_specific_functions_darwin",
feature = "platform_specific_functions_unix",
feature = "platform_specific_functions_windows"
))]
pub fn local(view: CalendarView) -> Date {
return Self::of(view, Time::unix().as_secs() as u128, local_timezone(), false);
}
pub fn from(view: CalendarView, unix_time: u128, time_zone: Zone, zone_in_unix: bool) -> Date {
return Self::of(view, unix_time, time_zone, zone_in_unix);
}
pub fn month(&self) -> Months {
return Months::from(self.month);
}
}
#[cfg(test)]
mod tests {
use super::{
CalendarView,
Date, Sign, Zone,
local_timezone
};
use libc::{
time_t, tm,
gmtime_r, localtime_r
};
use crate::{
types::{
planets::{
earth::{
calendar::{
constants::{
seconds::{SECONDS_IN_DAY}
}
}
}
}
}
};
#[test]
fn test_gmt_date_from_libc() {
let mut date_struct_libc: tm = unsafe { std::mem::zeroed::<tm>() };
let gmt_time_zone: Zone = Zone { sign: Sign::Unsigned, hours: 0_u8, minutes: 0_u8, seconds: 0_u8 };
let current_seconds: u64 = Date::now(CalendarView::Gregorian, gmt_time_zone).unix_time as u64;
for unix_time in (0..=current_seconds).step_by(SECONDS_IN_DAY as usize) {
let time_c: time_t = unix_time as time_t;
if unsafe { gmtime_r(&time_c, &mut date_struct_libc) } == std::ptr::null_mut() {
panic!("[ERROR]: Pointer is NULL (gmtime_r)!")
}
let date: Date = Date::from(CalendarView::Gregorian, unix_time as u128, gmt_time_zone, false);
assert_eq!(
(
(date_struct_libc.tm_year + 1900) as u64,
(date_struct_libc.tm_mon + 1) as u8,
(date_struct_libc.tm_mday) as u8,
date_struct_libc.tm_gmtoff.unsigned_abs() as u32
),
(
date.year,
date.month,
date.day,
date.time_zone.to_seconds()
)
)
}
}
#[test]
#[cfg(any(
feature = "platform_specific_functions_darwin",
feature = "platform_specific_functions_unix",
feature = "platform_specific_functions_windows"
))]
fn test_fuzz_date_with_libc() {
let (mut date, mut sign): (Date, Sign);
let mut date_struct_libc: tm = unsafe { std::mem::zeroed::<tm>() };
let current_seconds: u64 = Date::now(CalendarView::Gregorian, local_timezone()).unix_time as u64;
for unix_time in (0..=current_seconds).step_by(SECONDS_IN_DAY as usize) {
let time_c: time_t = unix_time as time_t;
if unsafe { localtime_r(&time_c, &mut date_struct_libc) } == std::ptr::null_mut() {
panic!("[ERROR]: Pointer is NULL (localtime_r)!")
}
if date_struct_libc.tm_gmtoff < 0 { sign = Sign::Signed } else { sign = Sign::Unsigned };
date = Date::from(CalendarView::Gregorian, unix_time as u128, Zone::from_seconds(sign, date_struct_libc.tm_gmtoff.unsigned_abs() as u32), false);
assert_eq!(
(
(date_struct_libc.tm_year + 1900) as u64,
(date_struct_libc.tm_mon + 1) as u8,
(date_struct_libc.tm_mday) as u8,
(date_struct_libc.tm_gmtoff).unsigned_abs() as u32
),
(
date.year,
date.month,
date.day,
date.time_zone.to_seconds()
)
)
}
}
}