pub use crate::types::data::time::{Time};
use crate::types::{
data::{
zone::{Sign, Zone}
}
};
#[cfg(any(
feature = "platform_specific_functions_darwin",
feature = "platform_specific_functions_unix",
feature = "platform_specific_functions_windows"
))]
use crate::platform::{
tz::{local_timezone},
};
impl Time {
pub fn utc() -> Time {
return Self::of(
Self::unix().as_secs() as u128,
Zone {
sign: Sign::Unsigned,
hours: 0, minutes: 0,
seconds: 0
},
true
);
}
pub fn now(time_zone: Zone) -> Time {
return Self::of(Self::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() -> Time {
return Self::of(Self::unix().as_secs() as u128, local_timezone(), false);
}
pub fn from(unix: u128, time_zone: Zone, zone_in_unix: bool) -> Time {
return Self::of(unix, time_zone, zone_in_unix);
}
}
#[cfg(test)]
mod tests {
use super::{
Time,
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_time_from_libc() {
let mut time_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 = Time::now(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 time_struct_libc) } == std::ptr::null_mut() {
panic!("[ERROR]: Pointer is NULL (gmtime_r)!")
}
let time: Time = Time::from(unix_time as u128, gmt_time_zone, false);
assert_eq!(
(
time_struct_libc.tm_hour as u8,
time_struct_libc.tm_min as u8,
time_struct_libc.tm_sec as u8,
time_struct_libc.tm_gmtoff.unsigned_abs() as u32
),
(
time.hours,
time.minutes,
time.seconds,
time.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_time_with_libc() {
let (mut time, mut sign): (Time, Sign);
let mut time_struct_libc: tm = unsafe { std::mem::zeroed::<tm>() };
let current_seconds: u64 = Time::now(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 time_struct_libc) } == std::ptr::null_mut() {
panic!("[ERROR]: Pointer is NULL (localtime_r)!")
}
if time_struct_libc.tm_gmtoff < 0 { sign = Sign::Signed } else { sign = Sign::Unsigned };
time = Time::from(unix_time as u128, Zone::from_seconds(sign, time_struct_libc.tm_gmtoff.unsigned_abs() as u32), false);
assert_eq!(
(
time_struct_libc.tm_hour as u8,
time_struct_libc.tm_min as u8,
time_struct_libc.tm_sec as u8,
time_struct_libc.tm_gmtoff.unsigned_abs() as u32
),
(
time.hours,
time.minutes,
time.seconds,
time.time_zone.to_seconds()
)
)
}
}
}