|
1 | 1 | using System;
|
| 2 | +using System.Collections.Generic; |
2 | 3 | using System.Text.RegularExpressions;
|
3 | 4 |
|
4 | 5 | namespace jittimes {
|
5 |
| - public struct Timestamp : IComparable { |
6 |
| - public Int64 seconds; |
7 |
| - public int milliseconds; |
8 |
| - public int nanoseconds; |
9 |
| - |
| 6 | + public record struct Timestamp (long nanoseconds) : IComparable { |
10 | 7 | static readonly Regex regex = new Regex ("^([0-9]+)s:([0-9]+)::([0-9]+)$");
|
11 | 8 |
|
12 | 9 | public static Timestamp Parse (string time)
|
13 | 10 | {
|
14 |
| - Timestamp ts = new Timestamp (); |
15 |
| - |
16 | 11 | var match = regex.Match (time);
|
17 |
| - if (!match.Success || match.Groups.Count <= 3) { |
18 |
| - ts.seconds = 0; |
19 |
| - ts.milliseconds = 0; |
20 |
| - ts.nanoseconds = 0; |
21 |
| - return ts; |
22 |
| - } |
| 12 | + if (!match.Success || match.Groups.Count <= 3) |
| 13 | + return default; |
23 | 14 |
|
24 |
| - ts.seconds = Convert.ToInt64 (match.Groups [1].Value); |
25 |
| - ts.milliseconds = Convert.ToInt32 (match.Groups [2].Value); |
26 |
| - ts.nanoseconds = Convert.ToInt32 (match.Groups [3].Value); |
27 |
| - |
28 |
| - return ts; |
| 15 | + var s = Convert.ToInt64 (match.Groups [1].Value); |
| 16 | + var ms = Convert.ToInt32 (match.Groups [2].Value); |
| 17 | + var ns = Convert.ToInt32 (match.Groups [3].Value); |
| 18 | + return new Timestamp (1_000_000*s + 1_000_000*ms + ns); |
29 | 19 | }
|
30 | 20 |
|
31 | 21 | static public Timestamp operator - (Timestamp ts1, Timestamp ts2)
|
32 |
| - { |
33 |
| - Timestamp result = new Timestamp (); |
34 |
| - |
35 |
| - if (ts1.nanoseconds >= ts2.nanoseconds) |
36 |
| - result.nanoseconds = ts1.nanoseconds - ts2.nanoseconds; |
37 |
| - else { |
38 |
| - result.nanoseconds = 1000000 + ts1.nanoseconds - ts2.nanoseconds; |
39 |
| - result.milliseconds--; |
40 |
| - } |
41 |
| - |
42 |
| - if (ts1.milliseconds >= ts2.milliseconds) |
43 |
| - result.milliseconds += ts1.milliseconds - ts2.milliseconds; |
44 |
| - else { |
45 |
| - result.milliseconds += 1000 + ts1.milliseconds - ts2.milliseconds; |
46 |
| - result.seconds--; |
47 |
| - } |
48 |
| - |
49 |
| - result.seconds += ts1.seconds - ts2.seconds; |
50 |
| - |
51 |
| - return result; |
52 |
| - } |
| 22 | + => new Timestamp (checked (ts1.nanoseconds - ts2.nanoseconds)); |
53 | 23 |
|
54 | 24 | static public Timestamp operator + (Timestamp ts1, Timestamp ts2)
|
55 |
| - { |
56 |
| - Timestamp result = new Timestamp { |
57 |
| - nanoseconds = ts1.nanoseconds + ts2.nanoseconds |
58 |
| - }; |
59 |
| - |
60 |
| - if (result.nanoseconds > 1000000) { |
61 |
| - result.milliseconds += result.nanoseconds / 1000000; |
62 |
| - result.nanoseconds %= 1000000; |
63 |
| - } |
64 |
| - |
65 |
| - result.milliseconds += ts1.milliseconds + ts2.milliseconds; |
66 |
| - |
67 |
| - if (result.milliseconds > 1000) { |
68 |
| - result.seconds += result.milliseconds / 1000; |
69 |
| - result.milliseconds %= 1000; |
70 |
| - } |
71 |
| - |
72 |
| - return result; |
73 |
| - } |
| 25 | + => new Timestamp (checked (ts1.nanoseconds + ts2.nanoseconds)); |
74 | 26 |
|
75 | 27 | public override string ToString ()
|
76 | 28 | {
|
77 |
| - var sec = seconds != 0 ? $"{seconds}(s):" : ""; |
78 |
| - |
79 |
| - return $"{sec}{milliseconds}::{nanoseconds}"; |
| 29 | + var remainder = Math.Abs (nanoseconds); |
| 30 | + var s = remainder / 1_000_000_000; |
| 31 | + remainder -= 1_000_000_000*s; |
| 32 | + var ms = remainder / 1_000_000; |
| 33 | + var ns = remainder - 1_000_000*ms; |
| 34 | + var sign = nanoseconds < 0 ? "-" : ""; |
| 35 | + var sec = s != 0 ? $"{s}(s):" : ""; |
| 36 | + return $"{sign}{sec}{ms}::{ns}"; |
80 | 37 | }
|
81 | 38 |
|
| 39 | + public Timestamp Positive () |
| 40 | + => new Timestamp (Math.Max (0L, nanoseconds)); |
| 41 | + |
82 | 42 | public double Milliseconds ()
|
83 |
| - { |
84 |
| - return seconds * 1000.0 + (double)milliseconds + nanoseconds / 1000000.0; |
85 |
| - } |
| 43 | + => nanoseconds / 1_000_000; |
86 | 44 |
|
87 | 45 | public int CompareTo (object o)
|
88 | 46 | {
|
89 | 47 | if (!(o is Timestamp other))
|
90 | 48 | throw new ArgumentException ("Object is not a Timestamp");
|
91 | 49 |
|
92 |
| - if (seconds > other.seconds) |
93 |
| - return 1; |
94 |
| - |
95 |
| - if (seconds < other.seconds) |
96 |
| - return -1; |
97 |
| - |
98 |
| - if (milliseconds > other.milliseconds) |
99 |
| - return 1; |
100 |
| - |
101 |
| - if (milliseconds < other.milliseconds) |
102 |
| - return -1; |
103 |
| - |
104 |
| - if (nanoseconds > other.nanoseconds) |
105 |
| - return 1; |
106 |
| - |
107 |
| - if (nanoseconds < other.nanoseconds) |
108 |
| - return -1; |
109 |
| - |
110 |
| - return 0; |
| 50 | + return Comparer<long>.Default.Compare (this.nanoseconds, other.nanoseconds); |
111 | 51 | }
|
112 | 52 | }
|
113 | 53 | }
|
0 commit comments