We're updating the issue view to help you get more done. 

Incorrect WEEK_OF_YEAR for Gregorian Calendar

Description

The WEEK_OF_YEAR value is computed incorrectly in some instances. Here is an
example run against ICU 1.3 demonstrating the problem:

Test4197699---

FAIL: Sat 01 Jan 2000 DOY=1 WOY=53, expected WOY=52
Sat 25 Dec 1999 DOY=359 WOY=51
Sun 26 Dec 1999 DOY=360 WOY=51
Mon 27 Dec 1999 DOY=361 WOY=52
Tue 28 Dec 1999 DOY=362 WOY=52
Wed 29 Dec 1999 DOY=363 WOY=52
Thu 30 Dec 1999 DOY=364 WOY=52
Fri 31 Dec 1999 DOY=365 WOY=52
Sat 01 Jan 2000 DOY=1 WOY=53
Sun 02 Jan 2000 DOY=2 WOY=53
Mon 03 Jan 2000 DOY=3 WOY=1
Tue 04 Jan 2000 DOY=4 WOY=1
Wed 05 Jan 2000 DOY=5 WOY=1
Thu 06 Jan 2000 DOY=6 WOY=1
Fri 07 Jan 2000 DOY=7 WOY=1
Ok: Mon 31 Dec 2001 DOY=365 WOY=1

---ERRORS (1) in Test4197699

The fix involves these diffs (approximately – this is taken from Java):

  •  

    •  

      • 1269,1276 ****
        // fall into the last week of the previous year; days at the end of
        // the year may fall into the first week of the next year.
        int relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6
        ! int relDowJan1 = (dayOfWeek - dayOfYear + 1 - getFirstDayOfWeek()) %
        7; // -6..6
        ! if (relDowJan1 < 0) relDowJan1 += 7; // 0..6
        int woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53
        if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) {
        ++woy;

      • 1286,1292 ----
        // fall into the last week of the previous year; days at the end of
        // the year may fall into the first week of the next year.
        int relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6
        ! int relDowJan1 = (dayOfWeek - dayOfYear + 701 - getFirstDayOfWeek()) %
        7; // 0..6
        int woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53
        if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) {
        ++woy;
        ***************

      • 1287,1297 ****
        else if (woy == 0) {
        // We are the last week of the previous year.
        int prevDoy = dayOfYear + yearLength(rawYear - 1);
        ! int prevDow = (dayOfWeek + 6) % 7; // 0..6; This is actually DOW-1
        % 7
        ! // The following line is unnecessary because weekNumber() will
        ! // do any needed normalization internally.
        ! // if (prevDow == 0) prevDow = 7; // 1..7
        ! woy = weekNumber(prevDoy, prevDow);
        }
        internalSet(WEEK_OF_YEAR, woy);


— 1303,1309 ---- else if (woy == 0) {
// We are the last week of the previous year.
int prevDoy = dayOfYear + yearLength(rawYear - 1);
! woy = weekNumber(prevDoy, dayOfWeek);
}
internalSet(WEEK_OF_YEAR, woy);

In addition, the docs need to be fleshed out on WEEK_OF_YEAR.

This is considered a Y2K bug.

{JDK bug 4197699}

Environment

Status

Assignee

TracBot

Reporter

TracBot

Labels

tracCreated

Oct 16, 1999, 2:06 AM

tracReporter

alan@8d6336d19dc03735

tracResolution

fixed

tracStatus

closed

Components

Priority

assess