1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use std;
use std::ops::Deref;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use atomic::AtomicI64;
const NO_VALUE: i64 = std::i64::MIN;
#[derive(Debug)]
pub struct Timestamp(AtomicI64);
impl Timestamp {
pub fn get(&self) -> Option<i64> {
let v = self.0.get();
if v == NO_VALUE {
None
} else {
Some(v)
}
}
pub(crate) fn new() -> Self {
Timestamp(AtomicI64::new(NO_VALUE))
}
pub(crate) fn from_value(v: Option<i64>) -> Self {
Timestamp(AtomicI64::new(v.unwrap_or(NO_VALUE)))
}
fn clear(&self) {
self.0.set(NO_VALUE);
}
fn set(&self, timestamp: i64) {
assert_ne!(timestamp, NO_VALUE);
self.0.set(timestamp);
}
fn set_time(&self, time: SystemTime) {
fn to_millis(d: Duration) -> i64 {
d.as_secs() as i64 * 1000 + i64::from(d.subsec_nanos()) / 1000 / 1000
}
if let Ok(duration) = time.duration_since(UNIX_EPOCH) {
self.set(to_millis(duration));
} else {
let duration = UNIX_EPOCH.duration_since(time).expect("Never fails");
self.set(-to_millis(duration));
}
}
fn set_now(&self) {
self.set_time(SystemTime::now());
}
}
#[derive(Debug)]
pub struct TimestampMut<'a>(&'a Timestamp);
impl<'a> TimestampMut<'a> {
pub fn set(&mut self, timestamp: i64) {
self.0.set(timestamp)
}
pub fn set_now(&mut self) {
self.0.set_now()
}
pub fn set_time(&mut self, time: SystemTime) {
self.0.set_time(time)
}
pub fn clear(&mut self) {
self.0.clear()
}
pub(crate) fn new(inner: &'a Timestamp) -> Self {
TimestampMut(inner)
}
}
impl<'a> Deref for TimestampMut<'a> {
type Target = Timestamp;
fn deref(&self) -> &Self::Target {
self.0
}
}
pub(crate) fn now_unixtime_seconds() -> f64 {
let now = SystemTime::now();
if let Ok(d) = now.duration_since(UNIX_EPOCH) {
duration_to_seconds(d)
} else {
let d = UNIX_EPOCH.duration_since(now).expect("Never fails");
-duration_to_seconds(d)
}
}
pub fn duration_to_seconds(d: Duration) -> f64 {
d.as_secs() as f64 + f64::from(d.subsec_nanos()) / 1_000_000_000.0
}