[
https://issues.apache.org/jira/browse/WW-5814?focusedWorklogId=1049996&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1049996
]
ASF GitHub Bot logged work on WW-5814:
--------------------------------------
Author: ASF GitHub Bot
Created on: 25/Oct/26 06:33
Start Date: 25/Oct/26 06:33
Worklog Time Spent: 10m
Work Description: lukaszlenart opened a new pull request, #2059:
URL: https://github.com/apache/struts/pull/2059
Fixes [WW-5814](https://issues.apache.org/jira/browse/WW-5814)
## Problem
`DateConverter` accepts ISO date-times ending in `Z` for `java.util.Date`
properties (since WW-5813 through explicit `'Z'`-literal formats), but treats
the `Z` as a literal. `2026-10-25T05:14:42.000Z`, the form JavaScript's
`Date.toISOString()` produces, is read in the server's default time zone, so a
UTC timestamp from a client is shifted by the server's offset. Numeric offsets
(`+02:00`) are rejected.
## Change
Reading `Z` as UTC changes the instant every existing `...Z` value converts
to, silently and with no conversion error, so it is opt-in:
- new constant `struts.converter.date.isoOffsetAware`
(`StrutsConstants.STRUTS_CONVERTER_DATE_ISO_OFFSET_AWARE`), default `false` in
`default.properties`
- `false`: unchanged, `Z` read as server-local time
- `true`: a `java.util.Date` target (and `Calendar`, which converts through
it) first tries `DateTimeFormatter.ISO_OFFSET_DATE_TIME`:
- `Z` means UTC
- numeric offsets are honoured
- 0-9 fractional digits are read as a fraction (with the flag off, `.5Z`
reads as 5 ms, because `.SSS` counts digits)
- input without an offset falls through to the existing formats unchanged
- a year outside `Date`'s range is a conversion error instead of an escaping
`IllegalArgumentException`
The default flips to `true` in 8.0.0:
[WW-5815](https://issues.apache.org/jira/browse/WW-5815).
Out of scope:
- `java.sql.Timestamp`, which has no ISO support today
- the `java.time` types: `OffsetDateTime` already parses offsets, and the
`Local*` types have no zone
- the JSON plugin's own date handling
## Tests
- Off by default, using the container's `DateConverter`.
- Setting the constant through `initDispatcher` turns the reading on.
- With the flag on:
- `Z` with and without milliseconds is read as UTC
- `+02:00` is honoured
- `.5` reads as half a second
- input without an offset keeps the local reading
- an out-of-range year is rejected
- The `Z` tests pin `Asia/Tokyo` as the default zone and restore it in
`tearDown`, so they cannot pass vacuously on a UTC build machine.
- Each test was seen failing first. The range check was also confirmed by
removing it.
- Full core suite on JDK 17 and JDK 25, plus the spring, junit,
javatemplates and json plugins on JDK 17, all green.
## Docs
- 7.5.0 release notes: the new constant.
- struts-site: the constant needs a line on the configuration page.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Issue Time Tracking
-------------------
Worklog Id: (was: 1049996)
Remaining Estimate: 0h
Time Spent: 10m
> DateConverter reads a trailing Z in an ISO date-time as server-local time
> instead of UTC
> ----------------------------------------------------------------------------------------
>
> Key: WW-5814
> URL: https://issues.apache.org/jira/browse/WW-5814
> Project: Struts 2
> Issue Type: Bug
> Components: Core
> Reporter: Lukasz Lenart
> Assignee: Lukasz Lenart
> Priority: Major
> Fix For: 7.5.0
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> {{DateConverter}} accepts ISO date-times such as {{1996-12-19T16:39:57Z}} and
> {{2026-10-25T05:14:42.000Z}} (the form JavaScript's {{Date.toISOString()}}
> produces) for {{java.util.Date}} properties, but treats the {{Z}} as a
> literal. The value is interpreted in the server's default time zone, so a UTC
> timestamp sent by a client is shifted by the server's offset.
> Other RFC 3339 forms are not accepted at all: a numeric offset ({{+02:00}}),
> and fractional seconds with other than three digits.
> h2. Background
> Before WW-5813 the converter ignored any text after
> {{yyyy-MM-dd'T'HH:mm:ss}}, so {{Z}} and {{.SSSZ}} were silently dropped.
> WW-5813 rejects trailing text, and keeps these two inputs working by adding
> {{yyyy-MM-dd'T'HH:mm:ss'Z'}} and {{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}} formats
> that preserve the previous local-time reading.
> {{OgnlUtilTest.testSetPropertiesDate}} pins that reading.
> h2. Fix
> Reading {{Z}} as UTC changes the instant every existing {{...Z}} value
> converts to (shifted by the server's offset), silently and without a
> conversion error, so it goes behind an opt-in flag:
> * new constant {{struts.converter.date.isoOffsetAware}}, default {{false}}
> * {{false}}: behaviour as released after WW-5813, {{Z}} read as server-local
> time
> * {{true}}: for {{java.util.Date}} (and {{Calendar}}, which goes through it)
> an ISO date-time with an offset is parsed with
> {{DateTimeFormatter.ISO_OFFSET_DATE_TIME}}, so {{Z}} means UTC, numeric
> offsets are honoured and 0-9 fractional digits are accepted
> {{java.sql.Timestamp}} (no ISO support today), the {{java.time}} types
> ({{OffsetDateTime}} already parses offsets) and the JSON plugin's own date
> handling are out of scope.
> The default flips to {{true}} in 8.0.0 under a separate ticket.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)