Coverage for src/lib.mys : 86%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from .system import now
3c"""source-before-namespace
4#include <ctime>
5"""
7func _pad(value: string, width: i64) -> string:
8 for _ in range(width - value.length()):
9 value = "0" + value
11 return value
13class TimeError(Error):
14 message: string
16class Time:
17 """Time in seconds and nanoseconds.
19 """
21 seconds: i64
22 nanoseconds: i32
24 func !=(self, other: Time) -> bool:
25 return not (self == other)
27 func >(self, other: Time) -> bool:
28 if self.seconds > other.seconds:
29 return True
30 elif self.seconds < other.seconds:
31 return False
32 elif self.nanoseconds > other.nanoseconds:
33 return True
34 else:
35 return False
37 func >=(self, other: Time) -> bool:
38 return self > other or self == other
40 func <=(self, other: Time) -> bool:
41 return self < other or self == other
43 func +=(self, other: Time):
44 self.seconds += other.seconds
45 self.nanoseconds += other.nanoseconds
47 if self.nanoseconds >= 1_000_000_000:
48 self.seconds += 1
49 self.nanoseconds -= 1_000_000_000
51 func -=(self, other: Time):
52 self.seconds -= other.seconds
53 self.nanoseconds -= other.nanoseconds
55 if self.nanoseconds < 0:
56 self.seconds -= 1
57 self.nanoseconds += 1_000_000_000
59 func +(self, seconds: i64) -> Time:
60 time = Time(seconds, 0)
61 time += self
63 return time
65 func -(self, seconds: i64) -> Time:
66 return self + -seconds
68class LocalDateTime:
69 """Date and time in the local time zone.
71 """
73 year: i32
74 month: u8
75 day: u8
76 hour: u8
77 minute: u8
78 second: u8
79 is_daylight_saving_time: bool
81 func __init__(self, time_since_epoch: Time? = None):
82 """Create a local date time object from given time since epoch. Uses
83 current system time if time_since_epoch is None.
85 """
87 ok = False
89 c"""
90 std::time_t t;
91 std::tm *tm_p;
93 if (time_since_epoch) {
94 t = time_since_epoch->seconds;
95 } else {
96 std::time(&t);
97 }
99 tm_p = std::localtime(&t);
101 if (tm_p != NULL) {
102 year = 1900 + tm_p->tm_year;
103 month = tm_p->tm_mon + 1;
104 day = tm_p->tm_mday;
105 hour = tm_p->tm_hour;
106 minute = tm_p->tm_min;
107 second = tm_p->tm_sec;
108 is_daylight_saving_time = tm_p->tm_isdst == 0 ? false : true;
109 ok = true;
110 }
111 """
113 if not ok:
114 raise TimeError("Time convertion failed.")
116 func to_time_since_epoch(self) -> Time:
117 """Return this date and time as time since epoch.
119 """
121 ok = False
122 time = Time(0, 0)
124 c"""
125 struct tm tm;
126 tm.tm_year = year - 1900;
127 tm.tm_mon = month - 1;
128 tm.tm_mday = day;
129 tm.tm_hour = hour;
130 tm.tm_min = minute;
131 tm.tm_sec = second;
132 tm.tm_isdst = is_daylight_saving_time;
134 time_t t = std::mktime(&tm);
136 if (t != -1) {
137 time->seconds = t;
138 ok = true;
139 }
140 """
142 if not ok:
143 raise TimeError("Time convertion failed.")
145 return time
147 func __str__(self) -> string:
148 year = _pad(str(self.year), 4)
149 month = _pad(str(self.month), 2)
150 day = _pad(str(self.day), 2)
151 hour = _pad(str(self.hour), 2)
152 minute = _pad(str(self.minute), 2)
153 second = _pad(str(self.second), 2)
155 return (f"{year}-{month}-{day} {hour}:{minute}:{second}")
157class UtcDateTime:
158 """Date and time in UTC.
160 """
162 year: i32
163 month: u8
164 day: u8
165 hour: u8
166 minute: u8
167 second: u8
169 func __init__(self, time_since_epoch: Time? = None):
170 """Create a UTC date time object from given time since epoch. Uses
171 current system time if time_since_epoch is None.
173 """
175 ok = False
177 c"""
178 std::time_t t;
179 std::tm *tm_p;
181 if (time_since_epoch) {
182 t = time_since_epoch->seconds;
183 } else {
184 std::time(&t);
185 }
187 tm_p = std::gmtime(&t);
189 if (tm_p != NULL) {
190 year = 1900 + tm_p->tm_year;
191 month = tm_p->tm_mon + 1;
192 day = tm_p->tm_mday;
193 hour = tm_p->tm_hour;
194 minute = tm_p->tm_min;
195 second = tm_p->tm_sec;
196 ok = true;
197 }
198 """
200 if not ok:
201 raise TimeError("Time convertion failed.")
203 func to_time_since_epoch(self) -> Time:
204 """Return this date and time as time since epoch.
206 """
208 ok = False
209 time = Time(0, 0)
211 c"""
212 struct tm tm;
213 tm.tm_year = year - 1900;
214 tm.tm_mon = month - 1;
215 tm.tm_mday = day;
216 tm.tm_hour = hour;
217 tm.tm_min = minute;
218 tm.tm_sec = second;
220 time_t t = timegm(&tm);
222 if (t != -1) {
223 time->seconds = t;
224 ok = true;
225 }
226 """
228 if not ok:
229 raise TimeError("Time convertion failed.")
231 return time
233 func __str__(self) -> string:
234 year = _pad(str(self.year), 4)
235 month = _pad(str(self.month), 2)
236 day = _pad(str(self.day), 2)
237 hour = _pad(str(self.hour), 2)
238 minute = _pad(str(self.minute), 2)
239 second = _pad(str(self.second), 2)
241 return (f"{year}-{month}-{day} {hour}:{minute}:{second} UTC")
243test time():
244 time = Time(5, 1)
245 assert time.seconds == 5
246 assert time.nanoseconds == 1
248test utc_date_time_from_time_since_epoch():
249 datetime = UtcDateTime(Time(0, 0))
250 assert datetime.year == 1970
251 assert datetime.month == 1
252 assert datetime.day == 1
253 assert datetime.hour == 0
254 assert datetime.minute == 0
255 assert datetime.second == 0
257test utc_date_time_from_time():
258 datetime = UtcDateTime(Time(1615130879, 0))
259 assert datetime.year == 2021
260 assert datetime.month == 3
261 assert datetime.day == 7
262 assert datetime.hour == 15
263 assert datetime.minute == 27
264 assert datetime.second == 59
266 time = datetime.to_time_since_epoch()
267 assert time.seconds == 1615130879
268 assert time.nanoseconds == 0
270test utc_date_time_now():
271 time = UtcDateTime().to_time_since_epoch()
272 assert time.seconds > now().seconds - 3600
273 assert time.seconds < now().seconds + 3600
275test local_date_time_from_time():
276 datetime = LocalDateTime(Time(1615130879, 0))
277 assert datetime.year == 2021
278 assert datetime.month == 3
279 assert datetime.minute == 27
280 assert datetime.second == 59
282 time = datetime.to_time_since_epoch()
283 assert time.seconds == 1615130879
284 assert time.nanoseconds == 0
286test local_date_time_now():
287 time = LocalDateTime().to_time_since_epoch()
288 assert time.seconds > now().seconds - 3600
289 assert time.seconds < now().seconds + 3600
291test add_times():
292 t = Time(10, 0)
294 t += Time(1, 0)
295 assert t.seconds == 11
296 assert t.nanoseconds == 0
298 t += Time(0, 1_000_000)
299 assert t.seconds == 11
300 assert t.nanoseconds == 1_000_000
302 t += Time(0, 999_000_001)
303 assert t.seconds == 12
304 assert t.nanoseconds == 1
306test subtract_times():
307 t = Time(10, 0)
309 t -= Time(1, 0)
310 assert t.seconds == 9
311 assert t.nanoseconds == 0
313 t -= Time(0, 1_000_000)
314 assert t.seconds == 8
315 assert t.nanoseconds == 999_000_000
317 t -= Time(0, 999_000_001)
318 assert t.seconds == 7
319 assert t.nanoseconds == 999_999_999
321test local_date_time_string():
322 assert str(LocalDateTime(Time(1615130879, 0))).starts_with("2021-03-0")
323 assert str(LocalDateTime(Time(1615130879, 0))).ends_with(":27:59")
325test utc_date_time_string():
326 assert str(UtcDateTime(Time(1615130879, 0))) == "2021-03-07 15:27:59 UTC"
328test compare_times():
329 assert Time(0, 0) == Time(0, 0)
330 assert Time(1, 0) != Time(0, 0)
331 assert Time(0, 0) < Time(1, 0)
332 assert Time(0, 1) > Time(0, 0)
333 assert not (Time(0, 0) > Time(0, 0))
334 assert Time(-1, 0) > Time(-2, 0)
335 assert Time(0, 1) >= Time(0, 0)
336 assert Time(0, 0) >= Time(0, 0)
337 assert Time(0, 0) <= Time(1, 0)
338 assert Time(0, 0) <= Time(0, 0)