use crate::zip::{ZipError, ZipResult}; use chrono::{DateTime, Datelike, NaiveDate, TimeZone, Timelike}; pub trait DosDateTime: Sized { fn from_dos_date_time(date: u16, time: u16, tz: Tz) -> ZipResult; #[allow(dead_code)] fn to_dos_date(&self) -> u16; fn to_dos_time(&self) -> u16; } impl DosDateTime for DateTime { #[inline] fn from_dos_date_time(date: u16, time: u16, tz: Tz) -> ZipResult { Ok(NaiveDate::from_ymd_opt( (date as i32 >> 9 & 0x7F) + 1980, date as u32 >> 5 & 0xF, date as u32 & 0x1F, ) .ok_or(ZipError::InvalidField("date"))? .and_hms_opt( (time as u32 >> 11) & 0x1F, (time as u32 >> 5) & 0x3F, (time as u32 & 0x1F) * 2, ) .ok_or(ZipError::InvalidField("time"))? .and_local_timezone(tz) .unwrap()) } #[inline] fn to_dos_date(&self) -> u16 { (self.year() as u16 - 1980 & 0x7F) << 9 | (self.month() as u16 & 0xF) << 5 | self.day() as u16 & 0x1F } #[inline] fn to_dos_time(&self) -> u16 { (self.hour() as u16 & 0x1F) << 11 | (self.minute() as u16 & 0x3F) << 5 | self.second() as u16 / 2 & 0x1F } }