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]

Reply via email to