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





Reply via email to