simpleqt opened a new pull request, #1857:
URL: https://github.com/apache/commons-lang/pull/1857
## Problem
`FastDateFormat` is both a `DatePrinter` and a `DateParser`, but for a
pattern containing **three or more 'Z' letters** the two halves disagree about
the zone-offset syntax, so the format output cannot be parsed back by the same
instance.
Reproduction (JDK 17, default zone America/New_York):
```java
FastDateFormat format = FastDateFormat.getInstance("yyyy-MM-ddZZZ");
String text = format.format(new Date(1698446400000L)); // "2023-10-27-04:00"
format.parse(text, new ParsePosition(0)); // null, error index
10 (the offset)
```
The round trip works for `Z` (RFC 822 `-0400`) and `ZZ` (ISO 8601 extended
`-04:00`), and fails for every count of `Z` from 3 to 8. JUnit repro:
`FastDateFormat_ZRoundTripTest` (2 of 3 tests fail on master, all pass with
this change).
## Root cause
The printer and the parser pick different rules per number of pattern
letters:
- `FastDatePrinter` (`select`, case `'Z'`): 1 letter →
`TimeZoneNumberRule.INSTANCE_NO_COLON` (`-0400`); 2 letters →
`Iso8601_Rule.ISO8601_HOURS_COLON_MINUTES` (`-04:00`); 3 or more letters →
`TimeZoneNumberRule.INSTANCE_COLON`, which also emits the extended `-04:00`
form (pinned by the existing test `FastDatePrinterTest#testTimeZoneAsZ`).
- `FastDateParser` (`getStrategy`, case `'Z'`): width 2 →
`ISO8601TimeZoneStrategy.ISO_8601_3_STRATEGY`, which accepts `+hh:mm`; any
other width → `TimeZoneStrategy`, whose numeric alternative `RFC_822_TIME_ZONE`
= `[+-](?:2[0-3]|[01]\d)[0-5]\d` only accepts the colon-less `+hhmm` form, so
`-04:00` never matches and the parse fails at the zone position.
## Fix
`FastDateParser` only: for `'Z'` with 3 or more letters, use a
`TimeZoneStrategy` variant whose numeric offset alternative also accepts the
ISO 8601 extended form, `[+-](?:2[0-3]|[01]\d):?[0-5]\d`. The matched text is
already handed to `FastTimeZone.getGmtTimeZone(...)`, whose GMT pattern
`(GMT)?(+|-)hh?(:?mm?)?` has always accepted the extended form, so no other
runtime change is needed.
Scoping notes:
- The new variant is only selected for `'Z'` widths >= 3, exactly where the
printer emits `+hh:mm`. `'z'` and 1–2-letter `'Z'` keep byte-for-byte their
previous strategies, so SimpleDateFormat parity is untouched — in particular
`FastDateParserSDFTest` ("z yyyy" / "-12:34 2010" must fail) still passes
unmodified.
- The variant accepts everything the old strategy accepted (zone names, RFC
822, `GMT+hh:mm`) plus the extended numeric form; it never rejects a previously
accepted input.
- The variant is cached per locale in its own small map (mirroring the
existing strategy caches) and cleared by the existing `FastDateParser.clear()`.
- `FastDateParserTest#testParseMissingTimeZoneName` constructs
`TimeZoneStrategy` reflectively; updated for the new constructor parameter.
## Testing
- New `FastDateFormat_ZRoundTripTest`:
- `testRoundTripOneAndTwoZ` — pins the already-working `Z` / `ZZ` behavior.
- `testRoundTripThreeOrMoreZ` — RED on master (`yyyy-MM-ddZZZ failed to
parse '2023-10-27-04:00' (error index 10)`), GREEN with the fix for 3–6 `Z`
letters.
- `testParseExplicitColonOffset` — `ZZZ` parses `2023-10-27-05:30` to the
same instant as the known-good `ZZ`.
- Neighbor suites re-run after the change (60k+ checks):
`FastDateParserTest` (43842), `FastDateParser_TimeZoneStrategyTest` (2043),
`FastDateParserSDFTest` (276), `FastDateParser_MoreOrLessTest`,
`FastDateFormatTest`, `FastDateFormat_PrinterTest`, `FastDatePrinterTest`,
`FastDateParserJava15BugTest`, `FastTimeZoneTest`, `DateUtilsTest`,
`DateFormatUtilsTest` — no failures.
## AI disclosure
Per the ASF Generative Tooling Guidance: this pull request was created with
AI assistance (ZCode agent) covering defect analysis, patch, tests, and this
description; a human contributor reviewed and submits it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]