|
23 | 23 | import java.time.OffsetDateTime;
|
24 | 24 | import java.util.Random;
|
25 | 25 | import java.util.TimeZone;
|
| 26 | +import java.util.function.ToLongFunction; |
26 | 27 |
|
27 | 28 | import org.junit.After;
|
28 | 29 | import org.junit.Before;
|
@@ -53,74 +54,100 @@ public void testDatePart() {
|
53 | 54 | assertEquals("Iteration: " + i + " " + j, j, Dates.dropDatePart(Dates.MILLISECONDS_IN_DAY * i + j));
|
54 | 55 | }
|
55 | 56 |
|
56 |
| - private static String removeDashes(final String iso8601) { |
57 |
| - final StringBuilder builder = new StringBuilder(iso8601); |
58 |
| - builder.delete(7, 8); |
59 |
| - builder.delete(4, 5); |
60 |
| - return builder.toString(); |
| 57 | + private static String removeDashes(final String str) { |
| 58 | + final StringBuilder b = new StringBuilder(str); |
| 59 | + b.delete(7, 8); |
| 60 | + b.delete(4, 5); |
| 61 | + return b.toString(); |
61 | 62 | }
|
62 | 63 |
|
63 |
| - private static void assertEpochEquals(final long expected, final String iso8601) throws ParseException { |
64 |
| - final long actual = Dates.iso8601ToEpochMilli(iso8601); |
65 |
| - assertEquals(iso8601 + ": " + expected + " != " + expected + " ~ " + Math.abs(expected - actual), expected, actual, 1); |
| 64 | + private static void assertEpochEquals(final ToLongFunction<String> fn, final long expected, final String str) throws ParseException { |
| 65 | + final long actual = fn.applyAsLong(str); |
| 66 | + assertEquals(str + ": " + expected + " != " + actual + " ~ " + Math.abs(expected - actual), expected, actual); |
66 | 67 | }
|
67 | 68 |
|
68 |
| - private static void testTime2(final long expected, final String iso8601) throws ParseException { |
69 |
| - assertEpochEquals(expected, iso8601); |
70 |
| - assertEpochEquals(expected, removeDashes(iso8601)); |
71 |
| - assertEpochEquals(expected, iso8601.replace(":", "")); |
72 |
| - assertEpochEquals(expected, iso8601.replace("T", "")); |
73 |
| - assertEpochEquals(expected, removeDashes(iso8601).replace(":", "")); |
74 |
| - assertEpochEquals(expected, removeDashes(iso8601).replace(":", "").replace("T", "")); |
| 69 | + private static void testTime3(final ToLongFunction<String> fn, final long expected, final String str) throws ParseException { |
| 70 | + assertEpochEquals(fn, expected, str); |
| 71 | + assertEpochEquals(fn, expected, removeDashes(str)); |
| 72 | + assertEpochEquals(fn, expected, str.replace(":", "")); |
| 73 | + assertEpochEquals(fn, expected, str.replace("T", "")); |
| 74 | + assertEpochEquals(fn, expected, removeDashes(str).replace(":", "")); |
| 75 | + assertEpochEquals(fn, expected, removeDashes(str).replace(":", "").replace("T", "")); |
75 | 76 | }
|
76 | 77 |
|
77 |
| - private static void testTime(final long expected, String iso8601) throws ParseException { |
78 |
| - testTime2(expected, iso8601); |
79 |
| - iso8601 = iso8601.substring(0, iso8601.length() - 1); |
| 78 | + private static void testTime2(final ToLongFunction<String> fn, final long expected, String str) throws ParseException { |
| 79 | + testTime3(fn, expected, str); |
| 80 | + str = str.substring(0, str.length() - 1); |
80 | 81 |
|
81 | 82 | final int hourOffset = (int)(Math.random() * 18);
|
82 | 83 | final String offset = Strings.pad(String.valueOf(hourOffset), RIGHT, 2, '0');
|
83 |
| - testTime2(expected - hourOffset * 60 * 60 * 1000, iso8601 + "+" + offset); |
84 |
| - testTime2(expected + hourOffset * 60 * 60 * 1000, iso8601 + "-" + offset); |
| 84 | + testTime3(fn, expected - hourOffset * 60 * 60 * 1000, str + "+" + offset); |
| 85 | + testTime3(fn, expected + hourOffset * 60 * 60 * 1000, str + "-" + offset); |
85 | 86 |
|
86 | 87 | final int minOffset = (int)(Math.random() * 60);
|
87 | 88 | final String offset2 = offset + ":" + Strings.pad(String.valueOf(minOffset), RIGHT, 2, '0');
|
88 |
| - testTime2(expected - (hourOffset * 60 + minOffset) * 60 * 1000, iso8601 + "+" + offset2); |
89 |
| - testTime2(expected + (hourOffset * 60 + minOffset) * 60 * 1000, iso8601 + "-" + offset2); |
| 89 | + testTime3(fn, expected - (hourOffset * 60 + minOffset) * 60 * 1000, str + "+" + offset2); |
| 90 | + testTime3(fn, expected + (hourOffset * 60 + minOffset) * 60 * 1000, str + "-" + offset2); |
90 | 91 |
|
91 | 92 | final String offset3 = offset + Strings.pad(String.valueOf(minOffset), RIGHT, 2, '0');
|
92 |
| - testTime2(expected - (hourOffset * 60 + minOffset) * 60 * 1000, iso8601 + "+" + offset3); |
93 |
| - testTime2(expected + (hourOffset * 60 + minOffset) * 60 * 1000, iso8601 + "-" + offset3); |
| 93 | + testTime3(fn, expected - (hourOffset * 60 + minOffset) * 60 * 1000, str + "+" + offset3); |
| 94 | + testTime3(fn, expected + (hourOffset * 60 + minOffset) * 60 * 1000, str + "-" + offset3); |
94 | 95 | }
|
95 | 96 |
|
96 |
| - private static long usingTimeApi(final String iso8601) { |
97 |
| - OffsetDateTime odt = OffsetDateTime.parse(iso8601); |
| 97 | + private static void testTime1(final ToLongFunction<String> fn, long expected, String str, final char del) throws ParseException { |
| 98 | + str = str.replace('T', del); |
| 99 | + testTime2(fn, expected, str); |
| 100 | + |
| 101 | + final int i = str.lastIndexOf('.') + 1; |
| 102 | + final int end = str.length() - 1; |
| 103 | + |
| 104 | + final String mils = str.substring(i, i + Math.min(3, end - i)); |
| 105 | + int millis = Integer.parseInt(mils); |
| 106 | + millis *= mils.length() == 1 ? 100 : mils.length() == 2 ? 10 : 1; |
| 107 | + |
| 108 | + str = str.substring(0, i - 1) + str.charAt(end); |
| 109 | + expected -= millis; |
| 110 | + |
| 111 | + testTime2(fn, expected, str); |
| 112 | + } |
| 113 | + |
| 114 | + private static long usingTimeApi(final String str) { |
| 115 | + OffsetDateTime odt = OffsetDateTime.parse(str); |
98 | 116 | Instant instant = odt.toInstant();
|
99 | 117 | return instant.getEpochSecond() * 1000;
|
100 | 118 | }
|
101 | 119 |
|
102 |
| - @Test |
103 |
| - public void testIso8601ToEpochMilli() throws ParseException { |
104 |
| - long timeMs = Dates.iso8601ToEpochMilli("2020-05-24T09:20:55.5Z"); |
105 |
| - testTime(timeMs, "2020-05-24T09:20:55.5Z"); |
106 |
| - testTime(timeMs, "2020-05-24T09:20:55.50Z"); |
107 |
| - testTime(timeMs, "2020-05-24T09:20:55.500Z"); |
108 |
| - testTime(timeMs, "2020-05-24T09:20:55.5002Z"); |
109 |
| - testTime(timeMs, "2020-05-24T09:20:55.50021Z"); |
110 |
| - testTime(timeMs, "2020-05-24T09:20:55.500210Z"); |
111 |
| - testTime(timeMs, "2020-05-24T09:20:55.5002101Z"); |
112 |
| - testTime(timeMs, "2020-05-24T09:20:55.50021012Z"); |
113 |
| - testTime(timeMs, "2020-05-24T09:20:55.500210123Z"); |
114 |
| - testTime(timeMs, "2020-05-24T09:20:55.5002101234Z"); |
115 |
| - testTime(timeMs, "2020-05-24T09:20:55.50021012345Z"); |
| 120 | + private static void testTime(final ToLongFunction<String> fn, final char del) throws ParseException { |
| 121 | + long timeMs = fn.applyAsLong("2020-05-24" + del + "09:20:55.5Z"); |
| 122 | + testTime1(fn, timeMs, "2020-05-24T09:20:55.5Z", del); |
| 123 | + testTime1(fn, timeMs, "2020-05-24T09:20:55.50Z", del); |
| 124 | + testTime1(fn, timeMs, "2020-05-24T09:20:55.500Z", del); |
| 125 | + testTime1(fn, timeMs, "2020-05-24T09:20:55.5002Z", del); |
| 126 | + testTime1(fn, timeMs, "2020-05-24T09:20:55.50021Z", del); |
| 127 | + testTime1(fn, timeMs, "2020-05-24T09:20:55.500210Z", del); |
| 128 | + testTime1(fn, timeMs, "2020-05-24T09:20:55.5002101Z", del); |
| 129 | + testTime1(fn, timeMs, "2020-05-24T09:20:55.50021012Z", del); |
| 130 | + testTime1(fn, timeMs, "2020-05-24T09:20:55.500210123Z", del); |
| 131 | + testTime1(fn, timeMs, "2020-05-24T09:20:55.5002101234Z", del); |
| 132 | + testTime1(fn, timeMs, "2020-05-24T09:20:55.50021012345Z", del); |
116 | 133 |
|
117 | 134 | for (int i = 0; i < 100; ++i) { // [N]
|
118 | 135 | timeMs = System.currentTimeMillis();
|
119 |
| - final String iso8601 = Dates.epochMilliToIso8601(timeMs); |
120 |
| - testTime(timeMs, iso8601); |
| 136 | + final String str = Dates.epochMilliToIso8601(timeMs); |
| 137 | + testTime1(fn, timeMs, str, del); |
121 | 138 | }
|
122 | 139 | }
|
123 | 140 |
|
| 141 | + @Test |
| 142 | + public void testRfc3339ToEpochMilli() throws ParseException { |
| 143 | + testTime(Dates::rfc3339ToEpochMilli, ' '); |
| 144 | + } |
| 145 | + |
| 146 | + @Test |
| 147 | + public void testIso8601ToEpochMilli() throws ParseException { |
| 148 | + testTime(Dates::iso8601ToEpochMilli, 'T'); |
| 149 | + } |
| 150 | + |
124 | 151 | @Test
|
125 | 152 | public void testDur() {
|
126 | 153 | for (int i = 0; i < 1000000; ++i) { // [N]
|
|
0 commit comments