1
2
3
4
5
6 namespace System
7 {
8 public class TimePoint
9 {
10 public nothrow TimePoint() : nanosecs(0)
11 {
12 }
13 public explicit nothrow TimePoint(long nanosecs_) : nanosecs(nanosecs_)
14 {
15 }
16 public inline nothrow long Rep() const
17 {
18 return nanosecs;
19 }
20 private long nanosecs;
21 }
22
23 public class Duration
24 {
25 public nothrow Duration() : nanosecs(0)
26 {
27 }
28 public explicit nothrow Duration(long nanosecs_) : nanosecs(nanosecs_)
29 {
30 }
31 public nothrow long Hours() const
32 {
33 return nanosecs / (3600 * long(1000000000));
34 }
35 public nothrow long Minutes() const
36 {
37 return nanosecs / (60 * long(1000000000));
38 }
39 public nothrow long Seconds() const
40 {
41 return nanosecs / long(1000000000);
42 }
43 public nothrow long Milliseconds() const
44 {
45 return nanosecs / long(1000000);
46 }
47 public nothrow long Microseconds() const
48 {
49 return nanosecs / long(1000);
50 }
51 public nothrow long Nanoseconds() const
52 {
53 return nanosecs;
54 }
55 public static nothrow Duration FromHours(long hours)
56 {
57 return Duration(3600 * long(1000000000) * hours);
58 }
59 public static nothrow Duration FromMinutes(long minutes)
60 {
61 return Duration(60 * long(1000000000) * minutes);
62 }
63 public static nothrow Duration FromSeconds(long seconds)
64 {
65 return Duration(long(1000000000) * seconds);
66 }
67 public static nothrow Duration FromMilliseconds(long milliseconds)
68 {
69 return Duration(long(1000000) * milliseconds);
70 }
71 public static nothrow Duration FromMicroseconds(long microseconds)
72 {
73 return Duration(long(1000) * microseconds);
74 }
75 public static nothrow Duration FromNanoseconds(long nanoseconds)
76 {
77 return Duration(nanoseconds);
78 }
79 public inline nothrow long Rep() const
80 {
81 return nanosecs;
82 }
83 private long nanosecs;
84 }
85
86 public inline nothrow bool operator==(const Duration& left, const Duration& right)
87 {
88 return left.Rep() == right.Rep();
89 }
90
91 public inline nothrow bool operator<(const Duration& left, const Duration& right)
92 {
93 return left.Rep() < right.Rep();
94 }
95
96 public inline nothrow bool operator==(const TimePoint& left, const TimePoint& right)
97 {
98 return left.Rep() == right.Rep();
99 }
100
101 public inline nothrow bool operator<(const TimePoint& left, const TimePoint& right)
102 {
103 return left.Rep() < right.Rep();
104 }
105
106 public inline nothrow Duration operator+(const Duration& left, const Duration& right)
107 {
108 return Duration(left.Rep() + right.Rep());
109 }
110
111 public inline nothrow Duration operator-(const Duration& left, const Duration& right)
112 {
113 return Duration(left.Rep() - right.Rep());
114 }
115
116 public inline nothrow Duration operator*(const Duration& left, const Duration& right)
117 {
118 return Duration(left.Rep() * right.Rep());
119 }
120
121 public inline nothrow Duration operator/(const Duration& left, const Duration& right)
122 {
123 return Duration(left.Rep() / right.Rep());
124 }
125
126 public inline nothrow Duration operator%(const Duration& left, const Duration& right)
127 {
128 return left.Rep() % right.Rep();
129 }
130
131 public inline nothrow Duration operator-(const TimePoint& left, const TimePoint& right)
132 {
133 long diff = left.Rep() - right.Rep();
134 return Duration(diff);
135 }
136
137 public inline nothrow TimePoint operator+(const TimePoint& tp, const Duration& d)
138 {
139 return TimePoint(tp.Rep() + d.Rep());
140 }
141
142 public inline nothrow TimePoint operator+(const Duration& d, const TimePoint& tp)
143 {
144 return TimePoint(tp.Rep() + d.Rep());
145 }
146
147 public inline nothrow TimePoint operator-(const TimePoint& tp, const Duration& d)
148 {
149 return TimePoint(tp.Rep() - d.Rep());
150 }
151
152 public nothrow TimePoint Now()
153 {
154 return TimePoint(RtNow());
155 }
156
157 public nothrow void Sleep(const Duration& duration)
158 {
159 RtSleep(duration.Rep());
160 }
161
162 public nothrow string DurationStr(const Duration& duration)
163 {
164 string s;
165 long hh = duration.Hours() % 24;
166 s.Append(cast<char>(cast<byte>('0') + cast<byte>(hh / 10 % 10)));
167 s.Append(cast<char>(cast<byte>('0') + cast<byte>(hh % 10)));
168 s.Append(':');
169 long mm = duration.Minutes() % 60;
170 s.Append(cast<char>(cast<byte>('0') + cast<byte>(mm / 10 % 10)));
171 s.Append(cast<char>(cast<byte>('0') + cast<byte>(mm % 10)));
172 s.Append(':');
173 long ss = duration.Seconds() % 60;
174 s.Append(cast<char>(cast<byte>('0') + cast<byte>(ss / 10 % 10)));
175 s.Append(cast<char>(cast<byte>('0') + cast<byte>(ss % 10)));
176 s.Append('.');
177 long ms = duration.Milliseconds() % 1000;
178 s.Append(cast<char>(cast<byte>('0') + cast<byte>(ms / 100 % 10)));
179 s.Append(cast<char>(cast<byte>('0') + cast<byte>(ms / 10 % 10)));
180 s.Append(cast<char>(cast<byte>('0') + cast<byte>(ms % 10)));
181 s.Append('.');
182 long us = duration.Microseconds() % 1000;
183 s.Append(cast<char>(cast<byte>('0') + cast<byte>(us / 100 % 10)));
184 s.Append(cast<char>(cast<byte>('0') + cast<byte>(us / 10 % 10)));
185 s.Append(cast<char>(cast<byte>('0') + cast<byte>(us % 10)));
186 return s;
187 }
188
189 public enum Month : sbyte
190 {
191 january = 1, february, march, april, may, june, july, august, september, october, november, december
192 }
193
194 public const int[] monthDays =
;
195
196 public nothrow int GetMonthDays(Month month, int year)
197 {
198 if (month == Month.february && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
199 {
200 return 29;
201 }
202 return monthDays[cast<sbyte>(month)];
203 }
204
205 public class Date
206 {
207 public nothrow Date() : year(0), month(Month.january), day(1)
208 {
209 }
210 public nothrow Date(short year_, Month month_, sbyte day_) : year(year_), month(month_), day(day_)
211 {
212 }
213 public inline nothrow short Year() const
214 {
215 return year;
216 }
217 public inline nothrow Month GetMonth() const
218 {
219 return month;
220 }
221 public inline nothrow sbyte Day() const
222 {
223 return day;
224 }
225 public nothrow Date AddDays(int n)
226 {
227 if (n > 0)
228 {
229 int d = day + n;
230 Month m = month;
231 short y = year;
232 int md = GetMonthDays(m, y);
233 while (d > md)
234 {
235 d = d - md;
236 if (m == Month.december)
237 {
238 m = Month.january;
239 ++y;
240 }
241 else
242 {
243 m = cast<Month>(cast<sbyte>(m) + 1);
244 }
245 md = GetMonthDays(m, y);
246 }
247 return Date(y, m, cast<sbyte>(d));
248 }
249 else if (n < 0)
250 {
251 int d = day + n;
252 Month m = month;
253 short y = year;
254 while (d < 1)
255 {
256 if (m == Month.january)
257 {
258 m = Month.december;
259 --y;
260 }
261 else
262 {
263 m = cast<Month>(cast<sbyte>(m) - 1);
264 }
265 d = d + GetMonthDays(m, y);
266 }
267 return Date(y, m, cast<sbyte>(d));
268 }
269 else
270 {
271 return *this;
272 }
273 }
274 public nothrow Date AddMonths(int n)
275 {
276 if (n > 0)
277 {
278 int m = cast<int>(cast<sbyte>(month)) + n;
279 short y = year;
280 int d = day;
281 while (m > 12)
282 {
283 m = m - 12;
284 ++y;
285 }
286 Month mnth = cast<Month>(cast<sbyte>(m));
287 int md = GetMonthDays(mnth, y);
288 if (d > md)
289 {
290 d = md;
291 }
292 return Date(y, mnth, cast<sbyte>(d));
293 }
294 else if (n < 0)
295 {
296 int m = cast<int>(cast<sbyte>(month)) + n;
297 short y = year;
298 int d = day;
299 while (m < 1)
300 {
301 m = m + 12;
302 --y;
303 }
304 Month mnth = cast<Month>(cast<sbyte>(m));
305 int md = GetMonthDays(mnth, y);
306 if (d > md)
307 {
308 d = md;
309 }
310 return Date(y, mnth, cast<sbyte>(d));
311 }
312 else
313 {
314 return *this;
315 }
316 }
317 public nothrow Date AddYears(short n)
318 {
319 short y = year + n;
320 int d = day;
321 int md = GetMonthDays(month, y);
322 if (d > md)
323 {
324 d = md;
325 }
326 return Date(y, month, cast<sbyte>(d));
327 }
328 public nothrow string ToString() const
329 {
330 return this->ToString(false);
331 }
332 public nothrow string ToString(bool omitDashes) const
333 {
334 string date;
335 date.Append(cast<char>(cast<short>('0') + ((year / 1000) % 10)));
336 date.Append(cast<char>(cast<short>('0') + ((year / 100) % 10)));
337 date.Append(cast<char>(cast<short>('0') + ((year / 10) % 10)));
338 date.Append(cast<char>(cast<short>('0') + (year % 10)));
339 if (!omitDashes)
340 {
341 date.Append('-');
342 }
343 date.Append(cast<char>(cast<sbyte>('0') + ((cast<sbyte>(month) / 10) % 10)));
344 date.Append(cast<char>(cast<sbyte>('0') + (cast<sbyte>(month) % 10)));
345 if (!omitDashes)
346 {
347 date.Append('-');
348 }
349 date.Append(cast<char>(cast<sbyte>('0') + ((day / 10) % 10)));
350 date.Append(cast<char>(cast<sbyte>('0') + (day % 10)));
351 return date;
352 }
353 private short year;
354 private Month month;
355 private sbyte day;
356 }
357
358 public nothrow Date GetCurrentDate()
359 {
360 short y;
361 sbyte m;
362 sbyte d;
363 RtGetCurrentDate(&y, &m, &d);
364 return Date(y, cast<Month>(m), d);
365 }
366
367 public nothrow bool operator==(const Date& left, const Date& right)
368 {
369 return left.Year() == right.Year() && left.GetMonth() == right.GetMonth() && left.Day() == right.Day();
370 }
371
372 public nothrow bool operator<(const Date& left, const Date& right)
373 {
374 if (left.Year() < right.Year()) return true;
375 if (left.Year() > right.Year()) return false;
376 if (left.GetMonth() < right.GetMonth()) return true;
377 if (left.GetMonth() > right.GetMonth()) return false;
378 return left.Day() < right.Day();
379 }
380
381 public class DateTime
382 {
383 public nothrow DateTime() : date(), secs(0)
384 {
385 }
386 public nothrow DateTime(Date date_) : date(date_), secs(0)
387 {
388 }
389 public nothrow DateTime(Date date_, int secs_) : date(date_), secs(secs_)
390 {
391 }
392 public inline nothrow Date GetDate() const
393 {
394 return date;
395 }
396 public inline nothrow int Hours() const
397 {
398 return secs / 3600;
399 }
400 public inline nothrow int Minutes() const
401 {
402 return secs / 60;
403 }
404 public inline nothrow int Seconds() const
405 {
406 return secs;
407 }
408 public nothrow string TimeString() const
409 {
410 string timeString;
411 int hh = Hours() % 24;
412 int mm = Minutes() % 60;
413 int ss = Seconds() % 60;
414 timeString.Append(cast<char>(cast<int>('0') + ((hh / 10) % 10)));
415 timeString.Append(cast<char>(cast<int>('0') + (hh % 10)));
416 timeString.Append(':');
417 timeString.Append(cast<char>(cast<int>('0') + ((mm / 10) % 10)));
418 timeString.Append(cast<char>(cast<int>('0') + (mm % 10)));
419 timeString.Append(':');
420 timeString.Append(cast<char>(cast<int>('0') + ((ss / 10) % 10)));
421 timeString.Append(cast<char>(cast<int>('0') + (ss % 10)));
422 return timeString;
423 }
424 public nothrow string ToString()
425 {
426 return this->ToString(false, false, false, false);
427 }
428 public nothrow string ToString(bool omitDashes, bool omitColons, bool omitMins, bool omitSecs)
429 {
430 string dateTime;
431 dateTime.Append(date.ToString(omitDashes));
432 dateTime.Append('T');
433 int hh = Hours() % 24;
434 int mm = Minutes() % 60;
435 int ss = Seconds() % 60;
436 dateTime.Append(cast<char>(cast<int>('0') + ((hh / 10) % 10)));
437 dateTime.Append(cast<char>(cast<int>('0') + (hh % 10)));
438 if (!omitMins)
439 {
440 if (!omitColons)
441 {
442 dateTime.Append(':');
443 }
444 dateTime.Append(cast<char>(cast<int>('0') + ((mm / 10) % 10)));
445 dateTime.Append(cast<char>(cast<int>('0') + (mm % 10)));
446 if (!omitSecs)
447 {
448 if (!omitColons)
449 {
450 dateTime.Append(':');
451 }
452 dateTime.Append(cast<char>(cast<int>('0') + ((ss / 10) % 10)));
453 dateTime.Append(cast<char>(cast<int>('0') + (ss % 10)));
454 }
455 }
456 return dateTime;
457 }
458 private Date date;
459 private int secs;
460 }
461
462 public const int secsInDay = cast<int>(24) * 3600;
463
464 public nothrow DateTime GetCurrentDateTime()
465 {
466 short y;
467 sbyte m;
468 sbyte d;
469 int secs;
470 RtGetCurrentDateTime(&y, &m, &d, &secs);
471 return DateTime(Date(y, cast<Month>(m), d), secs);
472 }
473
474 public nothrow bool operator==(const DateTime& left, const DateTime& right)
475 {
476 return left.GetDate() == right.GetDate() && left.Seconds() == right.Seconds();
477 }
478
479 public nothrow bool operator<(const DateTime& left, const DateTime& right)
480 {
481 if (left.GetDate() < right.GetDate()) return true;
482 if (left.GetDate() > right.GetDate()) return false;
483 return left.Seconds() < right.Seconds();
484 }
485
486 public class Timestamp
487 {
488 public nothrow Timestamp() : dateTime(), nanosecs()
489 {
490 }
491 public nothrow Timestamp(const DateTime& dateTime_, int nanosecs_) : dateTime(dateTime_), nanosecs(nanosecs_)
492 {
493 }
494 public nothrow const DateTime& GetDateTime() const
495 {
496 return dateTime;
497 }
498 public nothrow int GetNanoseconds() const
499 {
500 return nanosecs;
501 }
502 public nothrow string ToString() const
503 {
504 string s(dateTime.ToString());
505 s.Append('.').Append(Format(ToString(nanosecs), 9, FormatWidth.exact, FormatJustify.right, '0'));
506 return s;
507 }
508 private DateTime dateTime;
509 private int nanosecs;
510 }
511
512 public nothrow bool operator==(const Timestamp& left, const Timestamp& right)
513 {
514 return left.GetDateTime() == right.GetDateTime() && left.GetNanoseconds() == right.GetNanoseconds();
515 }
516
517 public nothrow bool operator<(const Timestamp& left, const Timestamp& right)
518 {
519 if (left.GetDateTime() < right.GetDateTime()) return true;
520 if (left.GetDateTime() > right.GetDateTime()) return false;
521 return left.GetNanoseconds() < right.GetNanoseconds();
522 }
523
524 public class TimestampProvider
525 {
526 static nothrow TimestampProvider() : instance(new TimestampProvider())
527 {
528 }
529 public static nothrow TimestampProvider& Instance()
530 {
531 return *instance;
532 }
533 private nothrow TimestampProvider()
534 {
535 Reset();
536 }
537 public nothrow Timestamp GetCurrentTimestamp()
538 {
539 if (GetCurrentDate() != startDateTime.GetDate())
540 {
541 Reset();
542 }
543 Duration elapsed = Now() - startTimePoint;
544 long elapsedNanosecs = elapsed.Nanoseconds();
545 int elapsedSecs = cast<int>(elapsedNanosecs / cast<long>(1000000000));
546 int nanosecs = cast<int>(elapsedNanosecs % cast<long>(1000000000));
547 Date date = startDateTime.GetDate();
548 int secs = startDateTime.Seconds() + elapsedSecs;
549 if (secs >= secsInDay)
550 {
551 date = date.AddDays(1);
552 secs = secs - secsInDay;
553 }
554 Timestamp timestamp(DateTime(date, secs), nanosecs);
555 return timestamp;
556 }
557 private nothrow void Reset()
558 {
559 startDateTime = GetCurrentDateTime();
560 startTimePoint = Now();
561 }
562 private static UniquePtr<TimestampProvider> instance;
563 private DateTime startDateTime;
564 private TimePoint startTimePoint;
565 }
566
567 public nothrow Timestamp GetCurrentTimestamp()
568 {
569 return TimestampProvider.Instance().GetCurrentTimestamp();
570 }
571 }