[ICU-31] Incorrect WEEK_OF_YEAR for Gregorian Calendar. Fixed algorithm, updated doc, added regression test.

X-Commit-URL: https://ssl.icu-project.org/trac/changeset/68
This commit is contained in:
Alan Liu 1999-10-16 00:25:13 +00:00
parent 4180724688
commit 81c41a1af7
2 changed files with 26 additions and 9 deletions

View file

@ -4,6 +4,7 @@
* COPYRIGHT: *
* (C) Copyright Taligent, Inc., 1997 *
* (C) Copyright International Business Machines Corporation, 1997-1998 *
* Copyright (C) 1999 Alan Liu and others. All rights reserved. *
* Licensed Material - Program-Property of IBM - All Rights Reserved. *
* US Government Users Restricted Rights - Use, duplication, or disclosure *
* restricted by GSA ADP Schedule Contract with IBM Corp. *
@ -32,6 +33,7 @@
* 07/28/98 stephen Sync up with JDK 1.2
* 09/14/98 stephen Changed type of kOneDay, kOneWeek to double.
* Fixed bug in roll()
* 10/15/99 aliu Fixed j31, incorrect WEEK_OF_YEAR computation.
********************************************************************************
*/
@ -467,8 +469,7 @@ GregorianCalendar::timeToFields(UDate theTime, bool_t quick, UErrorCode& status)
// 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.
int32_t relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6
int32_t relDowJan1 = (dayOfWeek - dayOfYear + 1 - getFirstDayOfWeek()) % 7; // -6..6
if (relDowJan1 < 0) relDowJan1 += 7; // 0..6
int32_t relDowJan1 = (dayOfWeek - dayOfYear + 701 - getFirstDayOfWeek()) % 7; // 0..6
int32_t woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53
if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) {
++woy;
@ -485,11 +486,7 @@ GregorianCalendar::timeToFields(UDate theTime, bool_t quick, UErrorCode& status)
else if (woy == 0) {
// We are the last week of the previous year.
int32_t prevDoy = dayOfYear + yearLength(rawYear - 1);
int32_t 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);
woy = weekNumber(prevDoy, dayOfWeek);
}
internalSet(WEEK_OF_YEAR, woy);

View file

@ -4,6 +4,7 @@
* COPYRIGHT: *
* (C) Copyright Taligent, Inc., 1997 *
* (C) Copyright International Business Machines Corporation, 1997-1999 *
* Copyright (C) 1999 Alan Liu and others. All rights reserved. *
* Licensed Material - Program-Property of IBM - All Rights Reserved. *
* US Government Users Restricted Rights - Use, duplication, or disclosure *
* restricted by GSA ADP Schedule Contract with IBM Corp. *
@ -20,6 +21,8 @@
* 09/04/98 stephen Re-sync with JDK 8/31 putback
* 09/14/98 stephen Changed type of kOneDay, kOneWeek to double.
* Fixed bug in roll()
* 10/15/99 aliu Fixed j31, incorrect WEEK_OF_YEAR computation.
* Added documentation of WEEK_OF_YEAR computation.
********************************************************************************
*/
@ -43,8 +46,25 @@
* avoid confusion, this Calendar always uses January 1. A manual adjustment may be made
* if desired for dates that are prior to the Gregorian changeover and which fall
* between January 1 and March 24.
* <P>
* Example for using GregorianCalendar:
*
* <p>Values calculated for the <code>WEEK_OF_YEAR</code> field range from 1 to
* 53. Week 1 for a year is the first week that contains at least
* <code>getMinimalDaysInFirstWeek()</code> days from that year. It thus
* depends on the values of <code>getMinimalDaysInFirstWeek()</code>,
* <code>getFirstDayOfWeek()</code>, and the day of the week of January 1.
* Weeks between week 1 of one year and week 1 of the following year are
* numbered sequentially from 2 to 52 or 53 (as needed).
*
* <p>For example, January 1, 1998 was a Thursday. If
* <code>getFirstDayOfWeek()</code> is <code>MONDAY</code> and
* <code>getMinimalDaysInFirstWeek()</code> is 4 (these are the values
* reflecting ISO 8601 and many national standards), then week 1 of 1998 starts
* on December 29, 1997, and ends on January 4, 1998. If, however,
* <code>getFirstDayOfWeek()</code> is <code>SUNDAY</code>, then week 1 of 1998
* starts on January 4, 1998, and ends on January 10, 1998; the first three days
* of 1998 then are part of week 53 of 1997.
*
* <p>Example for using GregorianCalendar:
* <pre>
* . // get the supported ids for GMT-08:00 (Pacific Standard Time)
* . int32_t idsCount;