1use crate::*;
2
3pub const LEAP_YEAR: [u64; 12] = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
5
6pub const COMMON_YEAR: [u64; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
8
9pub const DAYS: [&str; 7] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
11
12pub const MONTHS: [&str; 12] = [
14 "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
15];
16
17pub fn from_env_var() -> Lang {
27 let lang: Lang = env::var("LANG")
28 .unwrap_or_default()
29 .parse::<Lang>()
30 .unwrap_or_default();
31 lang
32}
33
34#[inline(always)]
44pub fn is_leap_year(year: u64) -> bool {
45 (year.is_multiple_of(4) && !year.is_multiple_of(100)) || year.is_multiple_of(400)
46}
47
48pub fn time() -> String {
54 let (year, month, day, hour, minute, second, _, _) = calculate_time();
55 let mut date_time: String = String::new();
56 write!(
57 &mut date_time,
58 "{year:04}-{month:02}-{day:02} {hour:02}:{minute:02}:{second:02}"
59 )
60 .unwrap_or_default();
61 date_time
62}
63
64pub fn date() -> String {
70 let (year, month, day, _, _, _, _, _) = calculate_time();
71 let mut date_time: String = String::new();
72 write!(&mut date_time, "{year:04}-{month:02}-{day:02}").unwrap_or_default();
73 date_time
74}
75
76pub fn compute_date(mut days_since_epoch: u64) -> (u64, u64, u64) {
86 let mut year: u64 = 1970;
87 loop {
88 let days_in_year: u64 = if is_leap_year(year) { 366 } else { 365 };
89 if days_since_epoch < days_in_year {
90 break;
91 }
92 days_since_epoch -= days_in_year as u64;
93 year += 1;
94 }
95 let mut month: u64 = 0;
96 for (i, &days) in COMMON_YEAR.iter().enumerate() {
97 let days_in_month = if i == 1 && is_leap_year(year) {
98 days + 1
99 } else {
100 days
101 };
102 if days_since_epoch < days_in_month as u64 {
103 month = i as u64 + 1;
104 return (year, month, days_since_epoch + 1);
105 }
106 days_since_epoch -= days_in_month as u64;
107 }
108
109 (year, month, 1)
110}
111
112pub fn gmt() -> String {
118 let now: SystemTime = SystemTime::now();
119 let duration_since_epoch: Duration = now.duration_since(UNIX_EPOCH).unwrap();
120 let timestamp: u64 = duration_since_epoch.as_secs();
121 let seconds_in_day: u64 = 86_400;
122 let days_since_epoch: u64 = timestamp / seconds_in_day;
123 let seconds_of_day: u64 = timestamp % seconds_in_day;
124 let hours: u64 = seconds_of_day / 3600;
125 let minutes: u64 = (seconds_of_day % 3600) / 60;
126 let seconds: u64 = seconds_of_day % 60;
127 let (year, month, day) = compute_date(days_since_epoch);
128 let weekday: usize = ((days_since_epoch + 4) % 7) as usize;
129 format!(
130 "{}, {:02} {} {} {:02}:{:02}:{:02} GMT",
131 DAYS[weekday],
132 day,
133 MONTHS[month as usize - 1],
134 year,
135 hours,
136 minutes,
137 seconds
138 )
139}
140
141pub fn year() -> u64 {
147 calculate_time().0
148}
149
150pub fn month() -> u64 {
156 calculate_time().1
157}
158
159pub fn day() -> u64 {
165 calculate_time().2
166}
167
168pub fn hour() -> u64 {
174 calculate_time().3
175}
176
177pub fn minute() -> u64 {
183 calculate_time().4
184}
185
186pub fn second() -> u64 {
192 calculate_time().5
193}
194
195pub fn millis() -> u64 {
201 calculate_time().6
202}
203
204pub fn micros() -> u64 {
210 calculate_time().7
211}
212
213pub fn calculate_time() -> (u64, u64, u64, u64, u64, u64, u64, u64) {
227 let start: SystemTime = SystemTime::now();
228 let duration: Duration = start.duration_since(UNIX_EPOCH).unwrap();
229 let total_seconds: u64 = duration.as_secs();
230 let nanoseconds: u64 = duration.subsec_nanos() as u64;
231 let milliseconds: u64 = nanoseconds / 1_000_000;
232 let microseconds: u64 = nanoseconds / 1_000;
233 let mut total_days: u64 = total_seconds / 86400;
234 let mut year: u64 = 1970;
235 while total_days >= if is_leap_year(year) { 366 } else { 365 } {
236 total_days -= if is_leap_year(year) { 366 } else { 365 };
237 year += 1;
238 }
239 let mut month: u64 = 1;
240 let month_days: [u64; 12] = if is_leap_year(year) {
241 LEAP_YEAR
242 } else {
243 COMMON_YEAR
244 };
245 while total_days >= month_days[month as usize - 1] {
246 total_days -= month_days[month as usize - 1];
247 month += 1;
248 }
249 let day: u64 = total_days + 1;
250 let remaining_seconds: u64 = total_seconds % 86400;
251 let timezone_offset: u64 = from_env_var().value();
252 let hour: u64 = ((remaining_seconds + timezone_offset) / 3600) % 24;
253 let minute: u64 = (remaining_seconds % 3600) / 60;
254 let second: u64 = remaining_seconds % 60;
255 (
256 year,
257 month,
258 day,
259 hour,
260 minute,
261 second,
262 milliseconds,
263 microseconds,
264 )
265}
266
267pub fn time_millis() -> String {
273 let (year, month, day, hour, minute, second, millisecond, _) = calculate_time();
274 let mut date_time: String = String::new();
275 write!(
276 &mut date_time,
277 "{year:04}-{month:02}-{day:02} {hour:02}:{minute:02}:{second:02}.{millisecond:03}"
278 )
279 .unwrap_or_default();
280 date_time
281}
282
283pub fn time_micros() -> String {
289 let (year, month, day, hour, minute, second, _, microseconds) = calculate_time();
290 let mut date_time: String = String::new();
291 write!(
292 &mut date_time,
293 "{year:04}-{month:02}-{day:02} {hour:02}:{minute:02}:{second:02}.{microseconds:06}"
294 )
295 .unwrap_or_default();
296 date_time
297}
298
299pub fn timestamp() -> u64 {
305 let timezone_offset: u64 = from_env_var().value();
306 SystemTime::now()
307 .duration_since(UNIX_EPOCH)
308 .unwrap()
309 .as_secs()
310 .saturating_add(timezone_offset)
311}
312
313pub fn timestamp_millis() -> u64 {
319 let timezone_offset: u64 = from_env_var().value();
320 let duration: Duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
321 (duration.as_secs().saturating_add(timezone_offset)) * 1000 + duration.subsec_millis() as u64
322}
323
324pub fn timestamp_micros() -> u64 {
330 let timezone_offset: u64 = from_env_var().value();
331 let duration: Duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
332 (duration.as_secs().saturating_add(timezone_offset)) * 1_000_000
333 + duration.subsec_micros() as u64
334}