1use std::fmt::Display;
2use std::ops::Add;
3use std::time::{Duration, SystemTime};
4
5#[macro_export]
6macro_rules! log {
7 ($state:expr, $($arg:tt)*) => {
8 use std::fmt::Write;
9 use std::thread::current;
10 use $crate::tool::{Datetime, TimeZone};
11
12 let th_id = format!("{:?}", current().id()).replace("ThreadId", "线程");
13 let th_name = &(current().name().unwrap().to_string() + "0")[0..5];
14
15 let now = Datetime::local(TimeZone::E08);
16
17 let mut output = String::new();
18 write!(&mut output, $($arg)*).unwrap();
19 println!("\x1b[36m{}{}\x1b[0m {} \x1b[{}\x1b[0m {}", th_name, &th_id, now, $state, output);
20 };
21}
22
23pub struct Datetime {
24 year: u64,
25 month: u64,
26 day: u64,
27 hour: u64,
28 minute: u64,
29 second: u64,
30}
31
32#[derive(Default)]
33pub enum TimeZone {
34 W12 = -12,
35 W11 = -11,
36 W10 = -10,
37 W09 = -9,
38 W08 = -8,
39 W07 = -7,
40 W06 = -6,
41 W05 = -5,
42 W04 = -4,
43 W03 = -3,
44 W02 = -2,
45 W01 = -1,
46 #[default]
47 UTC = 0,
48 E01 = 1,
49 E02 = 2,
50 E03 = 3,
51 E04 = 4,
52 E05 = 5,
53 E06 = 6,
54 E07 = 7,
55 E08 = 8,
56 E09 = 9,
57 E10 = 10,
58 E11 = 11,
59 E12 = 12,
60}
61
62impl Datetime {
63 pub fn local(time_zone: TimeZone) -> Self {
64 let mut dt = Self::default();
65 let system_now = SystemTime::now();
66 if let Ok(mut duration) = system_now.duration_since(std::time::UNIX_EPOCH) {
67 duration = duration.add(Duration::from_secs(
68 3600 * <TimeZone as Into<u64>>::into(time_zone),
69 ));
70 dt.second = duration.as_secs();
71
72 dt.day = dt.second / 86400 + 1; dt.second = dt.second % 86400; dt.hour = dt.second / 3600; dt.second = dt.second % 3600; dt.minute = dt.second / 60; dt.second = dt.second % 60; dt.year = 1970;
82 while dt.day >= days_in_year(dt.year) {
83 dt.day -= days_in_year(dt.year); dt.year += 1; }
86
87 let mut month = 1;
88 while dt.day >= days_in_month(dt.year, month) {
89 dt.day -= days_in_month(dt.year, month);
90 month += 1;
91 }
92 }
93 dt
94 }
95}
96
97impl Default for Datetime {
98 fn default() -> Self {
99 Self {
100 year: 1970,
101 month: 1,
102 day: 1,
103 hour: 0,
104 minute: 0,
105 second: 0,
106 }
107 }
108}
109
110impl Display for Datetime {
111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112 write!(
113 f,
114 "{:04}-{:02}-{:02} {:02}:{:02}:{:02}",
115 self.year, self.month, self.day, self.hour, self.minute, self.second
116 )
117 }
118}
119
120impl Into<u64> for TimeZone {
121 fn into(self) -> u64 {
122 self as u64
123 }
124}
125
126fn days_in_year(year: u64) -> u64 {
128 if (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) {
129 366
130 } else {
131 365
132 }
133}
134
135fn days_in_month(year: u64, month: u64) -> u64 {
137 match month {
138 1 | 3 | 5 | 7 | 8 | 10 | 12 => 31, 4 | 6 | 9 | 11 => 30, 2 => {
141 if (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) {
142 29
143 } else {
144 28
145 }
146 } _ => 0, }
149}