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
102
103
104
105
use std::time::UNIX_EPOCH;
use std::time::SystemTime;
static DAY_NAMES:[&str; 7] = ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"];
static DAYS_PER_MONTH: [i8; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
static MONTH_NAMES:[&str; 12] = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
#[derive(Debug)]
pub struct RFC2822Date {
year: i16,
month: i8,
day: i8,
hour: i8,
minute: i8,
second: i8,
millis: i16,
weekday: String,
}
impl RFC2822Date {
pub fn to_string(&self) -> String {
let day: String = pad_two(self.day + 1);
let month = MONTH_NAMES[self.month as usize];
let hour = pad_two(self.hour);
let minute = pad_two(self.minute);
let second = pad_two(self.second);
format!("{}, {} {} {} {}:{}:{} +0000", self.weekday, day, month, self.year, hour, minute, second)
}
pub fn now() -> RFC2822Date {
let millis = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("error")
.as_millis()
.try_into()
.unwrap();
RFC2822Date::new(millis)
}
pub fn new(millis: i64) -> RFC2822Date {
let mut d = RFC2822Date {
year: 0,
month: 0,
day: 0,
hour: 0,
minute: 0,
second: 0,
millis: 0,
weekday: "".to_string(),
};
d.millis = (millis % 1000) as i16;
let seconds = millis / 1000;
d.second = (seconds % 60) as i8;
let minutes = seconds / 60;
d.minute = (minutes % 60) as i8;
let hours = minutes / 60;
d.hour = (hours % 24) as i8;
let mut days = hours / 24;
let day_of_week = days % 7;
d.weekday = DAY_NAMES[day_of_week as usize].to_string();
let mut year = 0;
let mut leap;
loop {
let num_days = num_days(year+1970) as i64;
leap = num_days == 366;
if days < num_days { break; }
year += 1;
days -= num_days;
}
d.year = year + 1970 as i16;
let mut month = 0;
loop {
let mut num_days = DAYS_PER_MONTH[month] as i64;
if month == 1 && leap { num_days += 1; }
if days < num_days { break; }
month += 1;
days -= num_days;
}
d.month = month as i8;
d.day = days as i8;
d
}
}
fn pad_two(i: i8) -> String {
let mut s = i.to_string();
if s.len() < 2 { s = "0".to_string() + &s; }
s
}
fn num_days(year:i16) -> i16 {
if year % 4 == 0 {
if year % 400 == 0 || year % 100 != 0 {
return 366;
}
}
365
}