forked from M-Labs/rust-fatfs
Improve file creation time resolution to 1/100s
This commit is contained in:
parent
fda4b5ca5b
commit
099434c45d
1
TODO.md
1
TODO.md
@ -5,4 +5,3 @@ TODO
|
|||||||
* support for a volume label file in the root directory
|
* support for a volume label file in the root directory
|
||||||
* format volume API
|
* format volume API
|
||||||
* add method for getting DirEntry from path (suggested name: lookup)
|
* add method for getting DirEntry from path (suggested name: lookup)
|
||||||
* improve file creation time resulution data at offset 0x0D
|
|
||||||
|
@ -185,29 +185,31 @@ impl DirFileEntryData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn created(&self) -> DateTime {
|
fn created(&self) -> DateTime {
|
||||||
DateTime::from_u16(self.create_date, self.create_time_1)
|
DateTime::decode(self.create_date, self.create_time_1, self.create_time_0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accessed(&self) -> Date {
|
fn accessed(&self) -> Date {
|
||||||
Date::from_u16(self.access_date)
|
Date::decode(self.access_date)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modified(&self) -> DateTime {
|
fn modified(&self) -> DateTime {
|
||||||
DateTime::from_u16(self.modify_date, self.modify_time)
|
DateTime::decode(self.modify_date, self.modify_time, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_created(&mut self, date_time: DateTime) {
|
fn set_created(&mut self, date_time: DateTime) {
|
||||||
self.create_date = date_time.date.to_u16();
|
self.create_date = date_time.date.encode();
|
||||||
self.create_time_1 = date_time.time.to_u16();
|
let encoded_time = date_time.time.encode();
|
||||||
|
self.create_time_1 = encoded_time.0;
|
||||||
|
self.create_time_0 = encoded_time.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_accessed(&mut self, date: Date) {
|
fn set_accessed(&mut self, date: Date) {
|
||||||
self.access_date = date.to_u16();
|
self.access_date = date.encode();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_modified(&mut self, date_time: DateTime) {
|
fn set_modified(&mut self, date_time: DateTime) {
|
||||||
self.modify_date = date_time.date.to_u16();
|
self.modify_date = date_time.date.encode();
|
||||||
self.modify_time = date_time.time.to_u16();
|
self.modify_time = date_time.time.encode().0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "chrono")]
|
||||||
@ -457,12 +459,12 @@ pub struct Date {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Date {
|
impl Date {
|
||||||
pub(crate) fn from_u16(dos_date: u16) -> Self {
|
pub(crate) fn decode(dos_date: u16) -> Self {
|
||||||
let (year, month, day) = ((dos_date >> 9) + 1980, (dos_date >> 5) & 0xF, dos_date & 0x1F);
|
let (year, month, day) = ((dos_date >> 9) + 1980, (dos_date >> 5) & 0xF, dos_date & 0x1F);
|
||||||
Date { year, month, day }
|
Date { year, month, day }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_u16(&self) -> u16 {
|
fn encode(&self) -> u16 {
|
||||||
((self.year - 1980) << 9) | (self.month << 5) | self.day
|
((self.year - 1980) << 9) | (self.month << 5) | self.day
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -477,21 +479,24 @@ pub struct Time {
|
|||||||
/// Minutes after the hour - [0, 59]
|
/// Minutes after the hour - [0, 59]
|
||||||
pub min: u16,
|
pub min: u16,
|
||||||
/// Seconds after the minute - [0, 59]
|
/// Seconds after the minute - [0, 59]
|
||||||
///
|
|
||||||
/// Note: FAT filesystem has a resolution of 2 seconds.
|
|
||||||
pub sec: u16,
|
pub sec: u16,
|
||||||
/// Milliseconds after the second - [0, 999]
|
/// Milliseconds after the second - [0, 999]
|
||||||
pub millis: u16,
|
pub millis: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Time {
|
impl Time {
|
||||||
pub(crate) fn from_u16(dos_time: u16) -> Self {
|
pub(crate) fn decode(dos_time: u16, dos_time_hi_res: u8) -> Self {
|
||||||
let (hour, min, sec) = (dos_time >> 11, (dos_time >> 5) & 0x3F, (dos_time & 0x1F) * 2);
|
let hour = dos_time >> 11;
|
||||||
Time { hour, min, sec, millis: 0 }
|
let min = (dos_time >> 5) & 0x3F;
|
||||||
|
let sec = (dos_time & 0x1F) * 2 + (dos_time_hi_res as u16) / 2;
|
||||||
|
let millis = (dos_time_hi_res as u16 % 100) * 10;
|
||||||
|
Time { hour, min, sec, millis }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_u16(&self) -> u16 {
|
fn encode(&self) -> (u16, u8) {
|
||||||
(self.hour << 11) | (self.min << 5) | (self.sec / 2)
|
let dos_time = (self.hour << 11) | (self.min << 5) | (self.sec / 2);
|
||||||
|
let dos_time_hi_res = ((self.millis / 100) + (self.sec % 2) * 100) as u8;
|
||||||
|
(dos_time, dos_time_hi_res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,10 +512,10 @@ pub struct DateTime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DateTime {
|
impl DateTime {
|
||||||
pub(crate) fn from_u16(dos_date: u16, dos_time: u16) -> Self {
|
pub(crate) fn decode(dos_date: u16, dos_time: u16, dos_time_hi_res: u8) -> Self {
|
||||||
DateTime {
|
DateTime {
|
||||||
date: Date::from_u16(dos_date),
|
date: Date::decode(dos_date),
|
||||||
time: Time::from_u16(dos_time),
|
time: Time::decode(dos_time, dos_time_hi_res),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -526,7 +531,8 @@ impl From<Date> for chrono::Date<Local> {
|
|||||||
impl From<DateTime> for chrono::DateTime<Local> {
|
impl From<DateTime> for chrono::DateTime<Local> {
|
||||||
fn from(date_time: DateTime) -> Self {
|
fn from(date_time: DateTime) -> Self {
|
||||||
chrono::Date::<Local>::from(date_time.date)
|
chrono::Date::<Local>::from(date_time.date)
|
||||||
.and_hms(date_time.time.hour as u32, date_time.time.min as u32, date_time.time.sec as u32)
|
.and_hms_milli(date_time.time.hour as u32, date_time.time.min as u32,
|
||||||
|
date_time.time.sec as u32, date_time.time.millis as u32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,7 +556,7 @@ impl From<chrono::DateTime<Local>> for DateTime {
|
|||||||
hour: date_time.hour() as u16,
|
hour: date_time.hour() as u16,
|
||||||
min: date_time.minute() as u16,
|
min: date_time.minute() as u16,
|
||||||
sec: date_time.second() as u16,
|
sec: date_time.second() as u16,
|
||||||
millis: (date_time.nanosecond() / 1000) as u16,
|
millis: (date_time.nanosecond() / 1_000_000) as u16,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -732,6 +738,8 @@ impl <'a, T: ReadWriteSeek> DirEntry<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns file creation date and time.
|
/// Returns file creation date and time.
|
||||||
|
///
|
||||||
|
/// Resolution of the time field is 1/100s.
|
||||||
pub fn created(&self) -> DateTime {
|
pub fn created(&self) -> DateTime {
|
||||||
self.data.created()
|
self.data.created()
|
||||||
}
|
}
|
||||||
@ -742,6 +750,8 @@ impl <'a, T: ReadWriteSeek> DirEntry<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns file last modification date and time.
|
/// Returns file last modification date and time.
|
||||||
|
///
|
||||||
|
/// Resolution of the time field is 2s.
|
||||||
pub fn modified(&self) -> DateTime {
|
pub fn modified(&self) -> DateTime {
|
||||||
self.data.modified()
|
self.data.modified()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user