Hi everyone,
There is a problem with the Trinidad DateTimeRangeValidator where it
incorrectly flags the last date of its range as an error. JIRA:
https://issues.apache.org/jira/browse/TRINIDAD-61
Overview of the problem
1) The page contains a DateTimeRangeValidator with a maximum, e.g.
<tr:inputText value="#{clientValidation.date}">
<tr:validateDateTimeRange minimum="2007-01-01"
maximum="2007-12-31"/>
</tr:inputText>
2) ValidateDateTimeRangeTag uses TagUtils to convert from ISO 9601
format (yyyy-MM-dd) String to Date.
org.apache.myfaces.trinidadinternal.taglib.util.TagUtils.java:
private static DateFormat _ISO_DATE_FORMAT = new
SimpleDateFormat("yyyy-MM-dd");
static private final Date _parseISODate(String stringValue)
{
return _ISO_DATE_FORMAT.parse(stringValue);
}
-> SimpleDateFormat uses the default timezone to construct the Date,
e.g. in Pacific Time, 2007-12-31 00:00:00 PDT.
3) On the client, user enters 2007-12-31 (the last date of the range)
and tabs off. Client conversion and validation occurs.
TrDateTimeConverter.prototype._simpleDateParseImpl = function(..)
{
var parsedTime = new Date(0);
..
parsedTime.setFullYear(year); // year, month, date values derived
from parsing submittedValue with dateFormat pattern.
parsedTime.setMonth (month);
parsedTime.setDate (date);
}
The constructor "new Date(0)" corresponds to the Date (milliseconds)
constructor, returning a date with 0 milliseconds since 1 January 1970
00:00:00 UTC. The Date is in local timezone, hence there s a timezone
offset, E.g. in my timezone the Date is Dec 31 1969 16:00:00 PDT. After
setting the year, month, date the value is Dec 31 2007 16:00:00 PDT
4) The validator then compares the millisecond value of Dec 31 2007
16:00:00 PDT, against the millisecond value of maxDate 2007-12-31
00:00:00 PDT and throws a validation error, even though the value is
actually within range.
Couple of ways to fix
1) The server is creating the Date with all hours, minutes, seconds
components zeroed out. Shouldn't it be the maximum values for the
maxDate, e.g. 2007-12-31 23:59:59 PDT
Note, we may have timezone issues here if the server runs in a different
timezone than the client.
2) The client is using the "Date (milliseconds)" constructor, hence the
date is created with timezone offsets from UTC. Why not just use the
Date() constructor, which zeroes out the hh:mm:ss, then set the
individual parsed components?
Any comments on the proposed options above?
Thanks,
Yee-Wah