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
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
pub struct Timestamp(pub SystemTime);
impl Timestamp {
pub const ZERO: Timestamp = Timestamp(UNIX_EPOCH);
pub fn now() -> Timestamp {
return Timestamp(SystemTime::now());
}
pub fn duration_since(self, earlier: Timestamp) -> Result<Duration, std::time::SystemTimeError> {
return self.0.duration_since(earlier.0);
}
}
impl std::ops::Add<Duration> for Timestamp {
type Output = Timestamp;
fn add(self, rhs: Duration) -> Timestamp {
return Timestamp(self.0 + rhs);
}
}
impl std::ops::Sub<Duration> for Timestamp {
type Output = Timestamp;
fn sub(self, rhs: Duration) -> Timestamp {
return Timestamp(self.0 - rhs);
}
}
fn is_leap_year(y: u64) -> bool {
return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
}
fn days_in_month(y: u64, m: u64) -> u64 {
match m {
1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
4 | 6 | 9 | 11 => 30,
2 => if is_leap_year(y) { 29 } else { 28 },
_ => panic!("invalid month"),
}
}
pub fn secs_to_ymd_hms(mut secs: u64) -> (u64, u64, u64, u64, u64, u64) {
let s = secs % 60;
secs /= 60;
let min = secs % 60;
secs /= 60;
let h = secs % 24;
let mut days = secs / 24;
let mut y = 1970u64;
loop {
let days_in_year = if is_leap_year(y) { 366 } else { 365 };
if days < days_in_year {
break;
}
days -= days_in_year;
y += 1;
}
let mut mo = 1u64;
loop {
let dim = days_in_month(y, mo);
if days < dim {
break;
}
days -= dim;
mo += 1;
}
let day = days + 1;
return (y, mo, day, h, min, s);
}
pub fn ymd_hms_to_secs(y: u64, m: u64, d: u64, h: u64, min: u64, s: u64) -> u64 {
let mut days = 0u64;
for year in 1970..y {
days += if is_leap_year(year) { 366 } else { 365 };
}
for month in 1..m {
days += days_in_month(y, month);
}
days += d - 1;
return days * 86400 + h * 3600 + min * 60 + s;
}
|