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
14pub fn is_leap_year(year: u64) -> bool {
24 (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
25}
26
27pub fn time() -> String {
33 let (year, month, day, hour, minute, second, _, _) = calculate_time();
34 let mut date_time: String = String::new();
35 write!(
36 &mut date_time,
37 "{:04}-{:02}-{:02} {:02}:{:02}:{:02}",
38 year, month, day, hour, minute, second
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, "{:04}-{:02}-{:02}", year, month, day).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) as u64);
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) as u64;
105 let minutes: u64 = ((seconds_of_day % 3600) / 60) as u64;
106 let seconds: u64 = (seconds_of_day % 60) as u64;
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 "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:03}",
258 year, month, day, hour, minute, second, millisecond
259 )
260 .unwrap_or_default();
261 date_time
262}
263
264pub fn time_micros() -> String {
270 let (year, month, day, hour, minute, second, _, microseconds) = calculate_time();
271 let mut date_time: String = String::new();
272 write!(
273 &mut date_time,
274 "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:06}",
275 year, month, day, hour, minute, second, microseconds
276 )
277 .unwrap_or_default();
278 date_time
279}
280
281pub fn timestamp() -> u64 {
287 let timezone_offset: u64 = from_env_var().value();
288 SystemTime::now()
289 .duration_since(UNIX_EPOCH)
290 .unwrap()
291 .as_secs()
292 .saturating_add(timezone_offset)
293}
294
295pub fn timestamp_millis() -> u64 {
301 let timezone_offset: u64 = from_env_var().value();
302 let duration: Duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
303 (duration.as_secs().saturating_add(timezone_offset)) * 1000 + duration.subsec_millis() as u64
304}
305
306pub fn timestamp_micros() -> u64 {
312 let timezone_offset: u64 = from_env_var().value();
313 let duration: Duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
314 (duration.as_secs().saturating_add(timezone_offset)) * 1_000_000
315 + duration.subsec_micros() as u64
316}