Skip to content

Commit 0964d50

Browse files
committed
Don't convert SystemTime to DateTime<Utc> if cache has not expired
1 parent 5ed160c commit 0964d50

File tree

1 file changed

+36
-20
lines changed

1 file changed

+36
-20
lines changed

spdlog/src/formatter/local_time_cacher.rs

+36-20
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ where
2121

2222
#[derive(Clone)]
2323
pub(crate) struct LocalTimeCacher {
24-
stored_key: i64,
24+
stored_key: u64,
2525
cache_values: Option<CacheValues>,
2626
}
2727

@@ -74,30 +74,19 @@ impl LocalTimeCacher {
7474

7575
#[must_use]
7676
pub(crate) fn get(&mut self, system_time: SystemTime) -> TimeDate {
77-
self.get_inner(system_time.into())
78-
}
79-
80-
fn get_inner(&mut self, utc_time: DateTime<Utc>) -> TimeDate {
81-
const LEAP_BOUNDARY: u32 = 1_000_000_000;
82-
83-
let nanosecond = utc_time.nanosecond();
84-
let is_leap_second = nanosecond >= LEAP_BOUNDARY;
85-
let reduced_nanosecond = if is_leap_second {
86-
nanosecond - LEAP_BOUNDARY
87-
} else {
88-
nanosecond
89-
};
90-
let millisecond = reduced_nanosecond / 1_000_000;
77+
let since_epoch = system_time.duration_since(SystemTime::UNIX_EPOCH).unwrap();
78+
let nanosecond = since_epoch.subsec_nanos();
79+
let millisecond = nanosecond / 1_000_000;
9180

92-
let cache_key = utc_time.timestamp();
81+
let cache_key = since_epoch.as_secs();
9382
if self.cache_values.is_none() || self.stored_key != cache_key {
94-
self.cache_values = Some(CacheValues::new(utc_time));
83+
self.cache_values = Some(CacheValues::new(system_time));
9584
self.stored_key = cache_key;
9685
}
9786

9887
TimeDate {
9988
cached: self.cache_values.as_mut().unwrap(),
100-
nanosecond: reduced_nanosecond,
89+
nanosecond,
10190
millisecond,
10291
}
10392
}
@@ -299,9 +288,9 @@ impl<'a> TimeDate<'a> {
299288

300289
impl CacheValues {
301290
#[must_use]
302-
fn new(utc_time: DateTime<Utc>) -> Self {
291+
fn new(system_time: SystemTime) -> Self {
303292
CacheValues {
304-
local_time: utc_time.into(),
293+
local_time: system_time.into(),
305294
full_second_str: None,
306295
year: None,
307296
year_str: None,
@@ -372,3 +361,30 @@ impl fmt::Debug for TimeDateLazyLocked<'_> {
372361
.finish()
373362
}
374363
}
364+
365+
#[cfg(test)]
366+
mod tests {
367+
use super::*;
368+
369+
#[test]
370+
fn validation() {
371+
let mut cacher = LocalTimeCacher::new();
372+
373+
let begin = SystemTime::now();
374+
loop {
375+
let now = SystemTime::now();
376+
if now.duration_since(begin).unwrap().as_secs() >= 3 {
377+
break;
378+
}
379+
let from_cache = cacher.get(now);
380+
let from_chrono = DateTime::<Local>::from(now);
381+
382+
assert_eq!(
383+
from_cache.cached.local_time.with_nanosecond(0),
384+
from_chrono.with_nanosecond(0)
385+
);
386+
assert_eq!(from_cache.nanosecond, from_chrono.nanosecond());
387+
assert_eq!(from_cache.millisecond, from_chrono.nanosecond() / 1_000_000);
388+
}
389+
}
390+
}

0 commit comments

Comments
 (0)