You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Yee-wah Lee <ye...@oracle.com> on 2007/08/16 00:15:07 UTC

[Trinidad] fixing maximum on tr:DateTimeRangeValidator was (TRINIDAD-61) tr:validateDateTimeRange validation fails on last day of valid range

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






Re: [Trinidad] fixing maximum on tr:DateTimeRangeValidator was (TRINIDAD-61) tr:validateDateTimeRange validation fails on last day of valid range

Posted by Gabrielle Crawford <ga...@oracle.com>.
I'm not sure this is the answer you're looking for, but the client 
behavior should match the server behavior.

So what happens if you pass the same string to the server converter, 
does it fail there too? If the server converter zeros out and allows it 
to pass, then the client behavior should be the same.

Thanks,

Gab

Yee-wah Lee wrote:
> 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
>
>
>
>
>