1use crate::*;
2
3pub const LEAP_YEAR: [u64; 12] = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
5pub const COMMON_YEAR: [u64; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
7pub const DAYS: [&str; 7] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
9pub const MONTHS: [&str; 12] = [
11 "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
12];
13
14#[inline]
24pub fn is_leap_year(year: u64) -> bool {
25 (year.is_multiple_of(4) && !year.is_multiple_of(100)) || year.is_multiple_of(400)
26}
27
28pub fn time() -> String {
34 let (year, month, day, hour, minute, second, _, _) = calculate_time();
35 let mut date_time: String = String::new();
36 write!(
37 &mut date_time,
38 "{year:04}-{month:02}-{day:02} {hour:02}:{minute:02}:{second:02}"
39 )
40 .unwrap_or_default();
41 date_time
42}
43
44pub fn date() -> String {
50 let (year, month, day, _, _, _, _, _) = calculate_time();
51 let mut date_time: String = String::new();
52 write!(&mut date_time, "{year:04}-{month:02}-{day:02}").unwrap_or_default();
53 date_time
54}
55
56pub fn compute_date(mut days_since_epoch: u64) -> (u64, u64, u64) {
66 let mut year: u64 = 1970;
67 loop {
68 let days_in_year: u64 = if is_leap_year(year) { 366 } else { 365 };
69 if days_since_epoch < days_in_year {
70 break;
71 }
72 days_since_epoch -= days_in_year as u64;
73 year += 1;
74 }
75 let mut month: u64 = 0;
76 for (i, &days) in COMMON_YEAR.iter().enumerate() {
77 let days_in_month = if i == 1 && is_leap_year(year) {
78 days + 1
79 } else {
80 days
81 };
82 if days_since_epoch < days_in_month as u64 {
83 month = i as u64 + 1;
84 return (year, month, days_since_epoch + 1);
85 }
86 days_since_epoch -= days_in_month as u64;
87 }
88
89 (year, month, 1)
90}
91
92pub fn gmt() -> String {
98 let now: SystemTime = SystemTime::now();
99 let duration_since_epoch: Duration = now.duration_since(UNIX_EPOCH).unwrap();
100 let timestamp: u64 = duration_since_epoch.as_secs();
101 let seconds_in_day: u64 = 86_400;
102 let days_since_epoch: u64 = timestamp / seconds_in_day;
103 let seconds_of_day: u64 = timestamp % seconds_in_day;
104 let hours: u64 = seconds_of_day / 3600;
105 let minutes: u64 = (seconds_of_day % 3600) / 60;
106 let seconds: u64 = seconds_of_day % 60;
107 let (year, month, day) = compute_date(days_since_epoch);
108 let weekday: usize = ((days_since_epoch + 4) % 7) as usize;
109 format!(
110 "{}, {:02} {} {} {:02}:{:02}:{:02} GMT",
111 DAYS[weekday],
112 day,
113 MONTHS[month as usize - 1],
114 year,
115 hours,
116 minutes,
117 seconds
118 )
119}
120
121pub fn year() -> u64 {
127 calculate_time().0
128}
129
130pub fn month() -> u64 {
136 calculate_time().1
137}
138
139pub fn day() -> u64 {
145 calculate_time().2
146}
147
148pub fn hour() -> u64 {
154 calculate_time().3
155}
156
157pub fn minute() -> u64 {
163 calculate_time().4
164}
165
166pub fn second() -> u64 {
172 calculate_time().5
173}
174
175pub fn millis() -> u64 {
181 calculate_time().6
182}
183
184pub fn micros() -> u64 {
190 calculate_time().7
191}
192
193pub fn calculate_time() -> (u64, u64, u64, u64, u64, u64, u64, u64) {
207 let start: SystemTime = SystemTime::now();
208 let duration: Duration = start.duration_since(UNIX_EPOCH).unwrap();
209 let total_seconds: u64 = duration.as_secs();
210 let nanoseconds: u64 = duration.subsec_nanos() as u64;
211 let milliseconds: u64 = nanoseconds / 1_000_000;
212 let microseconds: u64 = nanoseconds / 1_000;
213 let mut total_days: u64 = total_seconds / 86400;
214 let mut year: u64 = 1970;
215 while total_days >= if is_leap_year(year) { 366 } else { 365 } {
216 total_days -= if is_leap_year(year) { 366 } else { 365 };
217 year += 1;
218 }
219 let mut month: u64 = 1;
220 let month_days: [u64; 12] = if is_leap_year(year) {
221 LEAP_YEAR
222 } else {
223 COMMON_YEAR
224 };
225 while total_days >= month_days[month as usize - 1] {
226 total_days -= month_days[month as usize - 1];
227 month += 1;
228 }
229 let day: u64 = total_days + 1;
230 let remaining_seconds: u64 = total_seconds % 86400;
231 let timezone_offset: u64 = from_env_var().value();
232 let hour: u64 = ((remaining_seconds + timezone_offset) / 3600) % 24;
233 let minute: u64 = (remaining_seconds % 3600) / 60;
234 let second: u64 = remaining_seconds % 60;
235 (
236 year,
237 month,
238 day,
239 hour,
240 minute,
241 second,
242 milliseconds,
243 microseconds,
244 )
245}
246
247pub fn time_millis() -> String {
253 let (year, month, day, hour, minute, second, millisecond, _) = calculate_time();
254 let mut date_time: String = String::new();
255 write!(
256 &mut date_time,
257 "{year:04}-{month:02}-{day:02} {hour:02}:{minute:02}:{second:02}.{millisecond:03}"
258 )
259 .unwrap_or_default();
260 date_time
261}
262
263pub fn time_micros() -> String {
269 let (year, month, day, hour, minute, second, _, microseconds) = calculate_time();
270 let mut date_time: String = String::new();
271 write!(
272 &mut date_time,
273 "{year:04}-{month:02}-{day:02} {hour:02}:{minute:02}:{second:02}.{microseconds:06}"
274 )
275 .unwrap_or_default();
276 date_time
277}
278
279pub fn timestamp() -> u64 {
285 let timezone_offset: u64 = from_env_var().value();
286 SystemTime::now()
287 .duration_since(UNIX_EPOCH)
288 .unwrap()
289 .as_secs()
290 .saturating_add(timezone_offset)
291}
292
293pub fn timestamp_millis() -> u64 {
299 let timezone_offset: u64 = from_env_var().value();
300 let duration: Duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
301 (duration.as_secs().saturating_add(timezone_offset)) * 1000 + duration.subsec_millis() as u64
302}
303
304pub fn timestamp_micros() -> u64 {
310 let timezone_offset: u64 = from_env_var().value();
311 let duration: Duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
312 (duration.as_secs().saturating_add(timezone_offset)) * 1_000_000
313 + duration.subsec_micros() as u64
314}