1use super::r#enum::from_env_var;
2use std::fmt::Write;
3use std::time::{Duration, SystemTime, UNIX_EPOCH};
4
5pub const LEAP_YEAR: [u64; 12] = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
7pub const COMMON_YEAR: [u64; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
9pub const DAYS: [&str; 7] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
11pub const MONTHS: [&str; 12] = [
13 "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
14];
15
16pub fn is_leap_year(year: u64) -> bool {
24 (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
25}
26
27pub fn time() -> String {
32 let (year, month, day, hour, minute, second, _, _) = calculate_time();
33 let mut date_time: String = String::new();
34 write!(
35 &mut date_time,
36 "{:04}-{:02}-{:02} {:02}:{:02}:{:02}",
37 year, month, day, hour, minute, second
38 )
39 .unwrap_or_default();
40 date_time
41}
42
43pub fn date() -> String {
48 let (year, month, day, _, _, _, _, _) = calculate_time();
49 let mut date_time: String = String::new();
50 write!(&mut date_time, "{:04}-{:02}-{:02}", year, month, day).unwrap_or_default();
51 date_time
52}
53
54pub fn compute_date(mut days_since_epoch: u64) -> (u64, u64, u64) {
59 let mut year: u64 = 1970;
60 loop {
61 let days_in_year: u64 = if is_leap_year(year) { 366 } else { 365 };
62 if days_since_epoch < days_in_year {
63 break;
64 }
65 days_since_epoch -= days_in_year as u64;
66 year += 1;
67 }
68 let mut month: u64 = 0;
69 for (i, &days) in COMMON_YEAR.iter().enumerate() {
70 let days_in_month = if i == 1 && is_leap_year(year) {
71 days + 1
72 } else {
73 days
74 };
75 if days_since_epoch < days_in_month as u64 {
76 month = i as u64 + 1;
77 return (year, month, (days_since_epoch + 1) as u64);
78 }
79 days_since_epoch -= days_in_month as u64;
80 }
81
82 (year, month, 1)
83}
84
85pub fn gmt() -> String {
90 let now: SystemTime = SystemTime::now();
91 let duration_since_epoch: Duration = now.duration_since(UNIX_EPOCH).unwrap();
92 let timestamp: u64 = duration_since_epoch.as_secs();
93 let seconds_in_day: u64 = 86_400;
94 let days_since_epoch: u64 = timestamp / seconds_in_day;
95 let seconds_of_day: u64 = timestamp % seconds_in_day;
96 let hours: u64 = (seconds_of_day / 3600) as u64;
97 let minutes: u64 = ((seconds_of_day % 3600) / 60) as u64;
98 let seconds: u64 = (seconds_of_day % 60) as u64;
99 let (year, month, day) = compute_date(days_since_epoch);
100 let weekday: usize = ((days_since_epoch + 4) % 7) as usize;
101 format!(
102 "{}, {:02} {} {} {:02}:{:02}:{:02} GMT",
103 DAYS[weekday],
104 day,
105 MONTHS[month as usize - 1],
106 year,
107 hours,
108 minutes,
109 seconds
110 )
111}
112
113pub fn year() -> u64 {
118 calculate_time().0
119}
120
121pub fn month() -> u64 {
126 calculate_time().1
127}
128
129pub fn day() -> u64 {
134 calculate_time().2
135}
136
137pub fn hour() -> u64 {
142 calculate_time().3
143}
144
145pub fn minute() -> u64 {
150 calculate_time().4
151}
152
153pub fn second() -> u64 {
158 calculate_time().5
159}
160
161pub fn millis() -> u64 {
166 calculate_time().6
167}
168
169pub fn micros() -> u64 {
174 calculate_time().7
175}
176
177pub fn calculate_time() -> (u64, u64, u64, u64, u64, u64, u64, u64) {
190 let start: SystemTime = SystemTime::now();
191 let duration: Duration = start.duration_since(UNIX_EPOCH).unwrap();
192 let total_seconds: u64 = duration.as_secs();
193 let nanoseconds: u64 = duration.subsec_nanos() as u64;
194 let milliseconds: u64 = nanoseconds / 1_000_000;
195 let microseconds: u64 = nanoseconds / 1_000;
196 let mut total_days: u64 = total_seconds / 86400;
197 let mut year: u64 = 1970;
198 while total_days >= if is_leap_year(year) { 366 } else { 365 } {
199 total_days -= if is_leap_year(year) { 366 } else { 365 };
200 year += 1;
201 }
202 let mut month: u64 = 1;
203 let month_days: [u64; 12] = if is_leap_year(year) {
204 LEAP_YEAR
205 } else {
206 COMMON_YEAR
207 };
208 while total_days >= month_days[month as usize - 1] {
209 total_days -= month_days[month as usize - 1];
210 month += 1;
211 }
212 let day: u64 = total_days + 1;
213 let remaining_seconds: u64 = total_seconds % 86400;
214 let timezone_offset: u64 = from_env_var().value();
215 let hour: u64 = ((remaining_seconds + timezone_offset) / 3600) % 24;
216 let minute: u64 = (remaining_seconds % 3600) / 60;
217 let second: u64 = remaining_seconds % 60;
218 (
219 year,
220 month,
221 day,
222 hour,
223 minute,
224 second,
225 milliseconds,
226 microseconds,
227 )
228}
229
230pub fn time_millis() -> String {
235 let (year, month, day, hour, minute, second, millisecond, _) = calculate_time();
236 let mut date_time: String = String::new();
237 write!(
238 &mut date_time,
239 "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:03}",
240 year, month, day, hour, minute, second, millisecond
241 )
242 .unwrap_or_default();
243 date_time
244}
245
246pub fn time_micros() -> String {
251 let (year, month, day, hour, minute, second, _, microseconds) = calculate_time();
252 let mut date_time: String = String::new();
253 write!(
254 &mut date_time,
255 "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:06}",
256 year, month, day, hour, minute, second, microseconds
257 )
258 .unwrap_or_default();
259 date_time
260}
261
262pub fn timestamp() -> u64 {
267 let timezone_offset: u64 = from_env_var().value();
268 SystemTime::now()
269 .duration_since(UNIX_EPOCH)
270 .unwrap()
271 .as_secs()
272 .saturating_add(timezone_offset)
273}
274
275pub fn timestamp_millis() -> u64 {
280 let timezone_offset: u64 = from_env_var().value();
281 let duration: Duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
282 (duration.as_secs().saturating_add(timezone_offset)) * 1000 + duration.subsec_millis() as u64
283}
284
285pub fn timestamp_micros() -> u64 {
290 let timezone_offset: u64 = from_env_var().value();
291 let duration: Duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
292 (duration.as_secs().saturating_add(timezone_offset)) * 1_000_000
293 + duration.subsec_micros() as u64
294}