1#[derive(Debug, Default)]
2pub struct DateTime {
3 seconds: u8,
4 minutes: u8,
5 hours: u8,
6 day: u8,
7 weekday: u8,
8 month: u8,
9 year: u64,
10 timestamp: u64,
11}
12
13use std::time::SystemTime;
14
15impl DateTime {
16 #[inline(always)]
23 pub fn now_utc() -> Self {
24 SystemTime::now().into()
25 }
26
27 #[inline(always)]
28 pub fn hour(&self) -> u8 {
29 self.hours
30 }
31
32 #[inline(always)]
33 pub fn minute(&self) -> u8 {
34 self.minutes
35 }
36
37 #[inline(always)]
38 pub fn second(&self) -> u8 {
39 self.seconds
40 }
41 #[inline(always)]
42 pub fn day(&self) -> u8 {
43 self.day
44 }
45
46 pub fn year(&self) -> u64 {
47 self.year
48 }
49
50 pub fn unix_timestamp(&self) -> u64 {
51 self.timestamp
52 }
53 pub fn unix_timestamp_millis(&self) -> u128 {
54 self.timestamp as u128 * 1000
55 }
56
57 pub fn unix_timestamp_nanos(&self) -> u128 {
58 self.timestamp as u128 * 1000000000
59 }
60
61 pub fn month(&self) -> Month {
62 match self.month {
63 1 => Month::January,
64 2 => Month::February,
65 3 => Month::March,
66 4 => Month::April,
67 5 => Month::May,
68 6 => Month::June,
69 7 => Month::July,
70 8 => Month::August,
71 9 => Month::September,
72 10 => Month::October,
73 11 => Month::November,
74 12 => Month::December,
75 _ => panic!("Month is not valid"),
76 }
77 }
78
79 #[inline(always)]
80 pub fn weekday(&self) -> Weekday {
81 match self.weekday {
82 0 => panic!("Week is not valid"),
83 1 => Weekday::Monday,
84 2 => Weekday::Tuesday,
85 3 => Weekday::Wednesday,
86 4 => Weekday::Thursday,
87 5 => Weekday::Friday,
88 6 => Weekday::Saturday,
89 7 => Weekday::Sunday,
90 _ => panic!("Week is not valid"),
91 }
92 }
93}
94
95#[derive(Debug, PartialEq)]
96pub enum Weekday {
97 Sunday = 1,
98 Monday,
99 Tuesday,
100 Wednesday,
101 Thursday,
102 Friday,
103 Saturday,
104}
105
106impl std::fmt::Display for Weekday {
107 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
108 match *self {
109 Weekday::Sunday => write!(f, "Sunday"),
110 Weekday::Monday => write!(f, "Monday"),
111 Weekday::Tuesday => write!(f, "Tuesday"),
112 Weekday::Wednesday => write!(f, "Wednesday"),
113 Weekday::Thursday => write!(f, "Thrusday"),
114 Weekday::Friday => write!(f, "Friday"),
115 Weekday::Saturday => write!(f, "Saturday"),
116 }
117 }
118}
119
120#[derive(Debug, PartialEq)]
121pub enum Month {
122 January = 1,
123 February,
124 March,
125 April,
126 May,
127 June,
128 July,
129 August,
130 September,
131 October,
132 November,
133 December,
134}
135
136impl std::fmt::Display for Month {
137 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
138 match *self {
139 Month::January => write!(f, "January"),
140 Month::February => write!(f, "February"),
141 Month::March => write!(f, "March"),
142 Month::April => write!(f, "April"),
143 Month::May => write!(f, "May"),
144 Month::June => write!(f, "June"),
145 Month::July => write!(f, "July"),
146 Month::August => write!(f, "August"),
147 Month::September => write!(f, "September"),
148 Month::October => write!(f, "October"),
149 Month::November => write!(f, "November"),
150 Month::December => write!(f, "December"),
151 }
152 }
153}
154
155impl From<SystemTime> for DateTime {
156 #[inline(always)]
159 fn from(system_time: SystemTime) -> Self {
160 let mut datetime = DateTime::default();
161
162 let duration = match system_time.duration_since(SystemTime::UNIX_EPOCH) {
163 Ok(duration) => duration,
164 Err(err) => err.duration(),
165 };
166
167 datetime.timestamp = duration.as_secs();
168
169 datetime.seconds = (datetime.timestamp % 60) as u8;
171 datetime.timestamp /= 60;
172 datetime.minutes = (datetime.timestamp % 60) as u8;
173 datetime.timestamp /= 60;
174 datetime.hours = (datetime.timestamp % 24) as u8;
175 datetime.timestamp /= 24;
176
177 let a = (4 * datetime.timestamp + 102032) / 146097 + 15;
179 let b = datetime.timestamp + 2442113 + a - (a / 4);
180 let mut c = (20 * b - 2442) / 7305;
181 let d = (b - 365 * c - (c / 4)) as u16;
182 let mut e = (d as u32 * 1000 / 30601) as u8;
183 let f = (d - e as u16 * 30 - e as u16 * 601 / 1000) as u8;
184
185 if e <= 13 {
187 c -= 4716;
188 e -= 1;
189 } else {
190 c -= 4715;
191 e -= 13;
192 }
193
194 datetime.year = c;
196 datetime.month = e;
197 datetime.day = f;
198
199 datetime.weekday = compute_day_of_week(c, e, f);
200
201 datetime
202 }
203}
204
205fn compute_day_of_week(mut y: u64, mut m: u8, d: u8) -> u8 {
206 if m <= 2 {
208 m += 12;
209 y -= 1;
210 }
211
212 let j = y / 100;
213 let k = y % 100;
215
216 let h: u64 = d as u64 + (26 * (m as u64 + 1) / 10) + k + (k / 4) + (5 * j) + (j / 4);
218
219 (((h + 5) % 7) as u8) + 1
221}