Hide keyboard shortcuts

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 

2 

3c"""source-before-namespace 

4#include <ctime> 

5""" 

6 

7func _pad(value: string, width: i64) -> string: 

8 for _ in range(width - value.length()): 

9 value = "0" + value 

10 

11 return value 

12 

13class TimeError(Error): 

14 message: string 

15 

16class Time: 

17 """Time in seconds and nanoseconds. 

18 

19 """ 

20 

21 seconds: i64 

22 nanoseconds: i32 

23 

24 func !=(self, other: Time) -> bool: 

25 return not (self == other) 

26 

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 

36 

37 func >=(self, other: Time) -> bool: 

38 return self > other or self == other 

39 

40 func <=(self, other: Time) -> bool: 

41 return self < other or self == other 

42 

43 func +=(self, other: Time): 

44 self.seconds += other.seconds 

45 self.nanoseconds += other.nanoseconds 

46 

47 if self.nanoseconds >= 1_000_000_000: 

48 self.seconds += 1 

49 self.nanoseconds -= 1_000_000_000 

50 

51 func -=(self, other: Time): 

52 self.seconds -= other.seconds 

53 self.nanoseconds -= other.nanoseconds 

54 

55 if self.nanoseconds < 0: 

56 self.seconds -= 1 

57 self.nanoseconds += 1_000_000_000 

58 

59 func +(self, seconds: i64) -> Time: 

60 time = Time(seconds, 0) 

61 time += self 

62 

63 return time 

64 

65 func -(self, seconds: i64) -> Time: 

66 return self + -seconds 

67 

68class LocalDateTime: 

69 """Date and time in the local time zone. 

70 

71 """ 

72 

73 year: i32 

74 month: u8 

75 day: u8 

76 hour: u8 

77 minute: u8 

78 second: u8 

79 is_daylight_saving_time: bool 

80 

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. 

84 

85 """ 

86 

87 ok = False 

88 

89 c""" 

90 std::time_t t; 

91 std::tm *tm_p; 

92 

93 if (time_since_epoch) { 

94 t = time_since_epoch->seconds; 

95 } else { 

96 std::time(&t); 

97 } 

98 

99 tm_p = std::localtime(&t); 

100 

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 """ 

112 

113 if not ok: 

114 raise TimeError("Time convertion failed.") 

115 

116 func to_time_since_epoch(self) -> Time: 

117 """Return this date and time as time since epoch. 

118 

119 """ 

120 

121 ok = False 

122 time = Time(0, 0) 

123 

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; 

133 

134 time_t t = std::mktime(&tm); 

135 

136 if (t != -1) { 

137 time->seconds = t; 

138 ok = true; 

139 } 

140 """ 

141 

142 if not ok: 

143 raise TimeError("Time convertion failed.") 

144 

145 return time 

146 

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) 

154 

155 return (f"{year}-{month}-{day} {hour}:{minute}:{second}") 

156 

157class UtcDateTime: 

158 """Date and time in UTC. 

159 

160 """ 

161 

162 year: i32 

163 month: u8 

164 day: u8 

165 hour: u8 

166 minute: u8 

167 second: u8 

168 

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. 

172 

173 """ 

174 

175 ok = False 

176 

177 c""" 

178 std::time_t t; 

179 std::tm *tm_p; 

180 

181 if (time_since_epoch) { 

182 t = time_since_epoch->seconds; 

183 } else { 

184 std::time(&t); 

185 } 

186 

187 tm_p = std::gmtime(&t); 

188 

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 """ 

199 

200 if not ok: 

201 raise TimeError("Time convertion failed.") 

202 

203 func to_time_since_epoch(self) -> Time: 

204 """Return this date and time as time since epoch. 

205 

206 """ 

207 

208 ok = False 

209 time = Time(0, 0) 

210 

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; 

219 

220 time_t t = timegm(&tm); 

221 

222 if (t != -1) { 

223 time->seconds = t; 

224 ok = true; 

225 } 

226 """ 

227 

228 if not ok: 

229 raise TimeError("Time convertion failed.") 

230 

231 return time 

232 

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) 

240 

241 return (f"{year}-{month}-{day} {hour}:{minute}:{second} UTC") 

242 

243test time(): 

244 time = Time(5, 1) 

245 assert time.seconds == 5 

246 assert time.nanoseconds == 1 

247 

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 

256 

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 

265 

266 time = datetime.to_time_since_epoch() 

267 assert time.seconds == 1615130879 

268 assert time.nanoseconds == 0 

269 

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 

274 

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 

281 

282 time = datetime.to_time_since_epoch() 

283 assert time.seconds == 1615130879 

284 assert time.nanoseconds == 0 

285 

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 

290 

291test add_times(): 

292 t = Time(10, 0) 

293 

294 t += Time(1, 0) 

295 assert t.seconds == 11 

296 assert t.nanoseconds == 0 

297 

298 t += Time(0, 1_000_000) 

299 assert t.seconds == 11 

300 assert t.nanoseconds == 1_000_000 

301 

302 t += Time(0, 999_000_001) 

303 assert t.seconds == 12 

304 assert t.nanoseconds == 1 

305 

306test subtract_times(): 

307 t = Time(10, 0) 

308 

309 t -= Time(1, 0) 

310 assert t.seconds == 9 

311 assert t.nanoseconds == 0 

312 

313 t -= Time(0, 1_000_000) 

314 assert t.seconds == 8 

315 assert t.nanoseconds == 999_000_000 

316 

317 t -= Time(0, 999_000_001) 

318 assert t.seconds == 7 

319 assert t.nanoseconds == 999_999_999 

320 

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") 

324 

325test utc_date_time_string(): 

326 assert str(UtcDateTime(Time(1615130879, 0))) == "2021-03-07 15:27:59 UTC" 

327 

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)