@@ -9,16 +9,34 @@ import kotlin.test.*
9
9
10
10
class InstantIsoStringsTest {
11
11
12
- /* Based on the ThreeTenBp project.
13
- * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
14
- */
12
+ @Test
13
+ fun parseAndFormatCanonicalStrings () {
14
+ for (canonicalString in arrayOf(
15
+ " 1970-01-01T00:00:00Z" ,
16
+ " 1970-01-01T00:00:00.100Z" ,
17
+ " 1970-01-01T00:00:00.010Z" ,
18
+ " 1970-01-01T00:00:00.001Z" ,
19
+ " 1970-01-01T00:00:00.000100Z" ,
20
+ " 1970-01-01T00:00:00.000010Z" ,
21
+ " 1970-01-01T00:00:00.000001Z" ,
22
+ " 1970-01-01T00:00:00.000000100Z" ,
23
+ " 1970-01-01T00:00:00.000000010Z" ,
24
+ " 1970-01-01T00:00:00.000000001Z" ,
25
+ )) {
26
+ val instant = parseInstant(canonicalString)
27
+ assertEquals(canonicalString, instant.toString())
28
+ }
29
+ }
30
+
15
31
@Test
16
32
fun parseIsoString () {
17
- val instants = arrayOf(
33
+ for ((str, seconds, nanos) in arrayOf(
34
+ // both upper and lower case is supported
18
35
Triple (" 1970-01-01T00:00:00Z" , 0 , 0 ),
19
36
Triple (" 1970-01-01t00:00:00Z" , 0 , 0 ),
20
37
Triple (" 1970-01-01T00:00:00z" , 0 , 0 ),
21
38
Triple (" 1970-01-01T00:00:00.0Z" , 0 , 0 ),
39
+ // all components are taken into accout
22
40
Triple (" 1970-01-01T00:00:00.000000000Z" , 0 , 0 ),
23
41
Triple (" 1970-01-01T00:00:00.000000001Z" , 0 , 1 ),
24
42
Triple (" 1970-01-01T00:00:00.100000000Z" , 0 , 100000000 ),
@@ -28,51 +46,145 @@ class InstantIsoStringsTest {
28
46
Triple (" 1970-01-01T00:01:01.000000001Z" , 61 , 1 ),
29
47
Triple (" 1970-01-01T01:00:00.000000000Z" , 3600 , 0 ),
30
48
Triple (" 1970-01-01T01:01:01.000000001Z" , 3661 , 1 ),
31
- Triple (" 1970-01-02T01:01:01.100000000Z" , 90061 , 100000000 ))
32
- instants.forEach {
33
- val (str, seconds, nanos) = it
49
+ Triple (" 1970-01-02T01:01:01.100000000Z" , 90061 , 100000000 ),
50
+ Triple (" 1970-02-02T01:01:01.100000000Z" , 31 * 86400 + 90061 , 100000000 ),
51
+ Triple (" 1971-02-02T01:01:01.100000000Z" , (365 + 31 ) * 86400 + 90061 , 100000000 ),
52
+ // current time
53
+ Triple (" 2024-07-15T16:06:29.461245691+02:00" , 1721052389 , 461245691 ),
54
+ )) {
34
55
val instant = parseInstant(str)
35
- assertEquals(seconds.toLong() * 1000 + nanos / 1000000 , instant.toEpochMilliseconds())
56
+ assertEquals(
57
+ seconds.toLong() * 1000 + nanos / 1000000 , instant.toEpochMilliseconds(),
58
+ " Parsed $instant from $str , with Unix time = `$seconds + 10^-9 * $nanos `"
59
+ )
36
60
}
61
+ }
37
62
63
+ @Test
64
+ fun nonParseableInstantStrings () {
38
65
for (nonIsoString in listOf (
66
+ // empty string
39
67
" " ,
68
+ // a non-empty but clearly unsuitable string
40
69
" x" ,
70
+ // something other than a sign at the beginning
41
71
" 1970-01-01T00:00:00Z" ,
72
+ // too many digits for the year
42
73
" +1234567890-01-01T00:00:00Z" ,
43
74
" -1234567890-01-01T00:00:00Z" ,
75
+ // not enough padding for the year
44
76
" 003-01-01T00:00:00Z" ,
45
77
" -003-01-01T00:00:00Z" ,
78
+ // a plus sign even though there is only 4 digits
46
79
" +1970-01-01T00:00:00Z" ,
80
+ // too many digits without padding
47
81
" 11970-01-01T00:00:00Z" ,
48
- " 1970-01-01T00:00:00Z " ,
82
+ // incorrect separators between the components
49
83
" 1970/01-01T00:00:00Z" ,
50
84
" 1970-01/01T00:00:00Z" ,
51
85
" 1970-01-01 00:00:00Z" ,
52
86
" 1970-01-01T00-00:00Z" ,
53
87
" 1970-01-01T00:00-00Z" ,
88
+ // non-digits where digits are expected
54
89
" 1970-X1-01T00:00:00Z" ,
55
90
" 1970-1X-01T00:00:00Z" ,
56
91
" 1970-11-X1T00:00:00Z" ,
57
92
" 1970-11-1XT00:00:00Z" ,
58
- " 1970-11-10T00:00:00Z" ,
59
93
" 1970-11-10TX0:00:00Z" ,
60
94
" 1970-11-10T0X:00:00Z" ,
61
95
" 1970-11-10T00:X0:00Z" ,
62
96
" 1970-11-10T00:0X:00Z" ,
63
97
" 1970-11-10T00:00:X0Z" ,
64
98
" 1970-11-10T00:00:0XZ" ,
99
+ // a non-ascii digit
65
100
" 1970-11-10T00:00:0٩Z" ,
101
+ // not enough components
102
+ " 1970-11-10T00:00Z" ,
103
+ // not enough components, even if the length is sufficient
104
+ " 1970-11-10T00:00+01:15" ,
105
+ // a dot without any fraction of the second following it
66
106
" 1970-11-10T00:00:00.Z" ,
107
+ // too many digits in the fraction of the second
67
108
" 1970-11-10T00:00:00.1234567890Z" ,
109
+ // out-of-range values
110
+ " 1970-00-10T00:00:00Z" ,
111
+ " 1970-13-10T00:00:00Z" ,
112
+ " 1970-01-32T00:00:00Z" ,
113
+ " 1970-02-29T00:00:00Z" ,
114
+ " 1972-02-30T00:00:00Z" ,
115
+ " 2000-02-30T00:00:00Z" ,
116
+ " 2100-02-29T00:00:00Z" ,
117
+ " 2004-02-30T00:00:00Z" ,
118
+ " 2005-02-29T00:00:00Z" ,
119
+ " 2005-04-31T00:00:00Z" ,
120
+ " 2005-04-01T24:00:00Z" ,
121
+ " 2005-04-01T00:60:00Z" ,
122
+ " 2005-04-01T00:00:60Z" ,
123
+ // leap second
124
+ " 1970-01-01T23:59:60Z" ,
125
+ // lack of padding
126
+ " 1970-1-10T00:00:00+05:00" ,
127
+ " 1970-10-1T00:00:00+05:00" ,
128
+ " 1970-10-10T0:00:00+05:00" ,
129
+ " 1970-10-10T00:0:00+05:00" ,
130
+ " 1970-10-10T00:00:0+05:00" ,
131
+ // no offset
132
+ " 1970-02-03T04:05:06.123456789" ,
133
+ // some invalid single-character offsets
134
+ " 1970-02-03T04:05:06.123456789A" ,
135
+ " 1970-02-03T04:05:06.123456789+" ,
136
+ " 1970-02-03T04:05:06.123456789-" ,
137
+ // too many components in the offset
138
+ " 1970-02-03T04:05:06.123456789+03:02:01:00" ,
139
+ " 1970-02-03T04:05:06.123456789+03:02:01.02" ,
140
+ // single-digit offset
141
+ " 1970-02-03T04:05:06.123456789+3" ,
142
+ // incorrect sign in the offset
143
+ " 1970-02-03T04:05:06.123456789 03" ,
144
+ // non-digits in the offset
145
+ " 1970-02-03T04:05:06.123456789+X3" ,
146
+ " 1970-02-03T04:05:06.123456789+1X" ,
147
+ " 1970-02-03T04:05:06.123456789+X3:12" ,
148
+ " 1970-02-03T04:05:06.123456789+1X:12" ,
149
+ " 1970-02-03T04:05:06.123456789+X3:12" ,
150
+ " 1970-02-03T04:05:06.123456789+13:X2" ,
151
+ " 1970-02-03T04:05:06.123456789+13:1X" ,
152
+ " 1970-02-03T04:05:06.123456789+X3:12:59" ,
153
+ " 1970-02-03T04:05:06.123456789+1X:12:59" ,
154
+ " 1970-02-03T04:05:06.123456789+X3:12:59" ,
155
+ " 1970-02-03T04:05:06.123456789+13:X2:59" ,
156
+ " 1970-02-03T04:05:06.123456789+13:1X:59" ,
157
+ " 1970-02-03T04:05:06.123456789+13:12:X9" ,
158
+ " 1970-02-03T04:05:06.123456789+13:12:5X" ,
159
+ // incorrect separators in the offset
160
+ " 1970-02-03T04:05:06.123456789+13/12" ,
161
+ " 1970-02-03T04:05:06.123456789+13/12:59" ,
162
+ " 1970-02-03T04:05:06.123456789+13:12/59" ,
163
+ " 1970-02-03T04:05:06.123456789+0130" ,
164
+ " 1970-02-03T04:05:06.123456789-0130" ,
165
+ // incorrect field length
166
+ " 1970-02-03T04:05:06.123456789-18:001" ,
167
+ // out-of-range offsets
168
+ " 1970-02-03T04:05:06.123456789+18:12:59" ,
169
+ " 1970-02-03T04:05:06.123456789-18:12:59" ,
170
+ " 1970-02-03T04:05:06.123456789+18:00:01" ,
171
+ " 1970-02-03T04:05:06.123456789-18:00:01" ,
172
+ " 1970-02-03T04:05:06.123456789+18:01" ,
173
+ " 1970-02-03T04:05:06.123456789-18:01" ,
174
+ " 1970-02-03T04:05:06.123456789+19" ,
175
+ " 1970-02-03T04:05:06.123456789-19" ,
176
+ // out-of-range fields of the offset
177
+ " 1970-02-03T04:05:06.123456789+01:12:60" ,
178
+ " 1970-02-03T04:05:06.123456789-01:12:60" ,
179
+ " 1970-02-03T04:05:06.123456789+01:60" ,
180
+ " 1970-02-03T04:05:06.123456789-01:60" ,
181
+ // lack of padding in the offset
182
+ " 1970-02-03T04:05:06.123456789+1:12:50" ,
183
+ " 1970-02-03T04:05:06.123456789+01:2:60" ,
184
+ " 1970-02-03T04:05:06.123456789+01:12:6" ,
68
185
)) {
69
186
assertInvalidFormat(nonIsoString) { parseInstant(nonIsoString) }
70
187
}
71
- assertInvalidFormat { parseInstant(" 1970-01-01T23:59:60Z" )}
72
- assertInvalidFormat { parseInstant(" 1970-01-01T24:00:00Z" )}
73
- assertInvalidFormat { parseInstant(" 1970-01-01T23:59Z" )}
74
- assertInvalidFormat { parseInstant(" x" ) }
75
- assertInvalidFormat { parseInstant(" 12020-12-31T23:59:59.000000000Z" ) }
76
188
// this string represents an Instant that is currently larger than Instant.MAX any of the implementations:
77
189
assertInvalidFormat { parseInstant (" +1000000001-12-31T23:59:59.000000000Z" ) }
78
190
}
@@ -130,6 +242,10 @@ class InstantIsoStringsTest {
130
242
private fun parseInstant (isoString : String ): Instant {
131
243
return parseIso(isoString)
132
244
}
245
+
246
+ private fun displayInstant (instant : Instant ): String {
247
+ return formatIso(instant)
248
+ }
133
249
}
134
250
135
251
0 commit comments