|
22 | 22 | import static org.junit.jupiter.api.Assertions.assertThrows; |
23 | 23 |
|
24 | 24 | import com.google.common.testing.EqualsTester; |
| 25 | +import java.time.format.DateTimeParseException; |
25 | 26 | import java.util.Calendar; |
26 | 27 | import java.util.Date; |
27 | 28 | import java.util.GregorianCalendar; |
@@ -237,24 +238,67 @@ void parseTimestampWithoutTimeZoneOffset() { |
237 | 238 |
|
238 | 239 | @Test |
239 | 240 | void parseTimestampWithTimeZoneOffset() { |
| 241 | + // Max values |
240 | 242 | assertThat(Timestamp.parseTimestampDuration("0001-01-01T00:00:00-00:00")) |
241 | 243 | .isEqualTo(Timestamp.MIN_VALUE); |
242 | 244 | assertThat(Timestamp.parseTimestampDuration("9999-12-31T23:59:59.999999999-00:00")) |
243 | 245 | .isEqualTo(Timestamp.MAX_VALUE); |
| 246 | + // Extreme values (close to min/max) |
| 247 | + assertThat(Timestamp.parseTimestampDuration("0001-01-01T00:00:00.000000001Z")) |
| 248 | + .isEqualTo(Timestamp.ofTimeSecondsAndNanos(Timestamp.MIN_VALUE.getSeconds(), 1)); |
| 249 | + assertThat(Timestamp.parseTimestampDuration("9999-12-31T23:59:59.999999998Z")) |
| 250 | + .isEqualTo(Timestamp.ofTimeSecondsAndNanos(Timestamp.MAX_VALUE.getSeconds(), 999999998)); |
| 251 | + // Common use cases |
244 | 252 | assertThat(Timestamp.parseTimestampDuration("2020-07-10T14:03:00-07:00")) |
245 | 253 | .isEqualTo(Timestamp.ofTimeSecondsAndNanos(1594414980, 0)); |
246 | 254 | assertThat(Timestamp.parseTimestampDuration("2020-12-06T19:21:12.123+05:30")) |
247 | 255 | .isEqualTo(Timestamp.ofTimeSecondsAndNanos(1607262672, 123000000)); |
248 | | - // we also confirm that parsing a timestamp with nano precision will behave the same as the |
| 256 | + // We also confirm that parsing a timestamp with nano precision will behave the same as the |
249 | 257 | // threeten counterpart |
250 | 258 | assertThat(Timestamp.parseTimestampDuration("2020-12-06T19:21:12.123+05:30")) |
251 | 259 | .isEqualTo(Timestamp.parseTimestamp("2020-12-06T19:21:12.123+05:30")); |
| 260 | + // Timestamps with fractional seconds at nanosecond level |
| 261 | + assertThat(Timestamp.parseTimestampDuration("2020-12-06T19:21:12.123456789+05:30")) |
| 262 | + .isEqualTo(Timestamp.ofTimeSecondsAndNanos(1607262672, 123456789)); |
| 263 | + // Fractional seconds beyond nanos should throw an exception |
| 264 | + assertThrows( |
| 265 | + DateTimeParseException.class, |
| 266 | + () -> Timestamp.parseTimestampDuration("2020-12-06T19:21:12.123456789321+05:30")); |
| 267 | + // Missing components (should throw exceptions) |
| 268 | + assertThrows( |
| 269 | + DateTimeParseException.class, () -> Timestamp.parseTimestampDuration("2020-12-06")); |
| 270 | + // Whitespace should not be supported |
| 271 | + assertThrows( |
| 272 | + DateTimeParseException.class, |
| 273 | + () -> Timestamp.parseTimestampDuration(" 2020-12-06T19:21:12.123+05:30 ")); |
| 274 | + // It should be case-insensitive |
| 275 | + assertThat(Timestamp.parseTimestampDuration("2020-07-10t14:03:00-07:00")) |
| 276 | + .isEqualTo(Timestamp.ofTimeSecondsAndNanos(1594414980, 0)); |
| 277 | + // Invalid time zone offsets |
| 278 | + assertThrows( |
| 279 | + DateTimeParseException.class, |
| 280 | + () -> Timestamp.parseTimestampDuration("2020-12-06T19:21:12.123+25:00")); |
| 281 | + assertThrows( |
| 282 | + DateTimeParseException.class, |
| 283 | + () -> Timestamp.parseTimestampDuration("2020-12-06T19:21:12.123-25:00")); |
| 284 | + // Int values for SecondOfMinute should be between 0 and 59 |
| 285 | + assertThrows( |
| 286 | + DateTimeParseException.class, |
| 287 | + () -> Timestamp.parseTimestampDuration("2016-12-31T23:59:60Z")); |
252 | 288 | } |
253 | 289 |
|
254 | 290 | @Test |
255 | 291 | void parseTimestampWithZoneString() { |
| 292 | + // Valid RFC 3339 timestamps with time zone names |
256 | 293 | assertThat(Timestamp.parseTimestampDuration("2020-12-06T08:51:12.123America/Toronto")) |
257 | 294 | .isEqualTo(Timestamp.ofTimeSecondsAndNanos(1607262672, 123000000)); |
| 295 | + assertThat(Timestamp.parseTimestampDuration("2023-04-10T22:42:10.123456789Europe/London")) |
| 296 | + .isEqualTo(Timestamp.ofTimeSecondsAndNanos(1681162930, 123456789)); |
| 297 | + |
| 298 | + // Invalid time zone names |
| 299 | + assertThrows( |
| 300 | + DateTimeParseException.class, |
| 301 | + () -> Timestamp.parseTimestampDuration("2020-12-06T19:21:12.123Invalid/TimeZone")); |
258 | 302 | } |
259 | 303 |
|
260 | 304 | @Test |
|
0 commit comments