Re: [Fwd: Re: [xslt] Bug in EXSLT date:week-in-year()]



William M. Brack wrote:
OK, thanks - I have applied this fix to CVS.  It caused two test results
(date.1 and datetime.1) to change, so I also updated those two test result
files.  Perhaps if you have a moment you might check whether you agree the
changed result is, in fact, the correct one.
I can confirm that 2000-02-29 is in week 9 (not 8 as in the previous date.1.out), but I have no mean to really test years such as "-0004", "-0001" or "0001"…

I also said in my previous mail that I didn't know whether week-in-year should return 0 or the last week-in-year of the previous year. It seems, from the exslt.org JavaScript and XSLT implementations, that the right answer is latter: there is no week 0, in any year, so date:week-in-year('2005-01-01') has to return 53, not 0.

A simple fix is to test if ret == 0 and then recurse using Dec. 31st of the previous year:

static long
_exsltDateWeekInYear(long yday, long yr)
{
   long fdiy, fdiw, ret;

fdiy = DAY_IN_YEAR(1, 1, yr);
/*
* Determine day-in-week (0=Sun, 1=Mon, etc.) then adjust so Monday
* is the first day-in-week
*/
fdiw = (_exsltDateDayInWeek(fdiy, yr) + 6) % 7;


   ret = (yday + fdiw) / 7;

   /* ISO 8601 adjustment, 3 is Thu */
   if (fdiw <= 3)
       ret += 1;

   /* There is no week 0, compute last week of previous year */
   if (ret == 0) {
       ret = _exsltDateWeekInYear(DAY_IN_YEAR(31, 12, yr-1), yr-1);
   }

   return ret;
}

static double
exsltDateWeekInYear (const xmlChar *dateTime)
{
   exsltDateValPtr dt;
   long diy, ret;

   if (dateTime == NULL) {
#ifdef WITH_TIME
   dt = exsltDateCurrent();
   if (dt == NULL)
#endif
       return xmlXPathNAN;
   } else {
       dt = exsltDateParse(dateTime);
       if (dt == NULL)
           return xmlXPathNAN;
       if ((dt->type != XS_DATETIME) && (dt->type != XS_DATE)) {
           exsltDateFreeDate(dt);
           return xmlXPathNAN;
       }
   }

   diy = DAY_IN_YEAR(dt->value.date.day, dt->value.date.mon,
                     dt->value.date.year);

   ret = _exsltDateWeekInYear(diy, dt->value.date.year);

   _exsltDateFreeDate(dt);

   return (double) ret;
}

This seems to be OK (not compiled, not tested).

Note that this might have incidence on date formatting and parsing from date:format-date() and date/parse-date() (which are not implemented by LibEXSLT at this time) when the 'w' format pattern is used.
With Oracle's TO_DATE, there are 'YYYY' and 'IYYY' patterns. With 2005-01-01, the former will return '2005' and the latter '2004'. The 'IYYY' patter (I for ISO) is meant to be used with the 'IW' pattern (ISO Week-in-year), so that 'IYYY-IW' formatting of 2005-01-01 would be '2004-53'.
I don't know how Java deals with this kind of date formatting…


--
Thomas Broyer
Atol Conseils et Développement
03.80.68.81.68




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]