diff --git a/icu4c/source/i18n/calendar.h b/icu4c/source/i18n/calendar.h index bcda31e8621..2b4189fba05 100644 --- a/icu4c/source/i18n/calendar.h +++ b/icu4c/source/i18n/calendar.h @@ -20,7 +20,9 @@ * 05/01/97 aliu Made equals(), before(), after() arguments const. * 05/20/97 aliu Replaced fAreFieldsSet with fAreFieldsInSync and * fAreAllFieldsSet. -* 07/27/98 stephen Sync up with JDK 1.2 +* 07/27/98 stephen Sync up with JDK 1.2 +* 11/15/99 weiv added YEAR_WOY and DOW_LOCAL +* to EDateFields ******************************************************************************** */ @@ -168,6 +170,9 @@ public: MILLISECOND, // Example: 0..999 ZONE_OFFSET, // Example: -12*U_MILLIS_PER_HOUR..12*U_MILLIS_PER_HOUR DST_OFFSET, // Example: 0 or U_MILLIS_PER_HOUR +// here will go names for 'Y' and 'e' + YEAR_WOY, // 'Y' Example: 1..big number + DOW_LOCAL, // 'e' Example: 1..7 FIELD_COUNT, DAY_OF_MONTH = DATE // Synonyms diff --git a/icu4c/source/i18n/datefmt.h b/icu4c/source/i18n/datefmt.h index 8d43d49d26a..d23f7e8f240 100644 --- a/icu4c/source/i18n/datefmt.h +++ b/icu4c/source/i18n/datefmt.h @@ -19,6 +19,7 @@ * 02/19/97 aliu Converted from java. * 04/01/97 aliu Added support for centuries. * 07/23/98 stephen JDK 1.2 sync +* 11/15/99 weiv Added support for week of year/day of week formatting ******************************************************************************** */ @@ -143,6 +144,9 @@ public: // HOUR0_FIELD is used for the zero-based 12-hour clock. // For example, 11:30 PM + 1 hour results in 00:30 AM. kTimezoneField, // TIMEZONE field alignment. + kYearWOYField, // Corrected year for week representation + kDOWLocalField, // localized day of week + /** diff --git a/icu4c/source/i18n/dtfmtsym.cpp b/icu4c/source/i18n/dtfmtsym.cpp index 2eee0e9fbf7..d781d72a4e5 100644 --- a/icu4c/source/i18n/dtfmtsym.cpp +++ b/icu4c/source/i18n/dtfmtsym.cpp @@ -33,7 +33,8 @@ // generic date-format pattern symbols. For their meanings, see class docs // for SimpleDateFormat -UnicodeString DateFormatSymbols::fgPatternChars = "GyMdkHmsSEDFwWahKz"; +//UnicodeString DateFormatSymbols::fgPatternChars = "GyMdkHmsSEDFwWahKz"; +UnicodeString DateFormatSymbols::fgPatternChars = "GyMdkHmsSEDFwWahKzYe"; //------------------------------------------------------ // Strings of last resort. These are only used if we have no resource diff --git a/icu4c/source/i18n/gregocal.cpp b/icu4c/source/i18n/gregocal.cpp index 75e5bbc0107..b1eccce598a 100644 --- a/icu4c/source/i18n/gregocal.cpp +++ b/icu4c/source/i18n/gregocal.cpp @@ -36,6 +36,8 @@ * 10/15/99 aliu Fixed j31, incorrect WEEK_OF_YEAR computation. * 10/15/99 aliu Fixed j32, cannot set date to Feb 29 2000 AD. * {JDK bug 4210209 4209272} +* 11/15/99 weiv Added YEAR_WOY and DOW_LOCAL computation +* to timeToFields method, updated kMinValues, kMaxValues & kLeastMaxValues ******************************************************************************** */ @@ -106,17 +108,19 @@ const UDate GregorianCalendar::LATEST_SUPPORTED_MILLIS = 4503599627370495.0 * MILLISECOND 0 0 999 999 * ZONE_OFFSET -12* -12* 12* 12* * DST_OFFSET 0 0 1* 1* + * YEAR_WOY 1 1 140742 144683 + * DOW_LOCAL 1 1 7 7 * * (*) In units of one-hour */ const int32_t GregorianCalendar::kMinValues[] = { - 0,1,0,1,0,1,1,1,-1,0,0,0,0,0,0,-12*U_MILLIS_PER_HOUR,0 + 0,1,0,1,0,1,1,1,-1,0,0,0,0,0,0,-12*U_MILLIS_PER_HOUR,0,1,1 }; const int32_t GregorianCalendar::kLeastMaxValues[] = { - 1,140742,11,52,4,28,365,7,4,1,11,23,59,59,999,12*U_MILLIS_PER_HOUR,1*U_MILLIS_PER_HOUR + 1,140742,11,52,4,28,365,7,4,1,11,23,59,59,999,12*U_MILLIS_PER_HOUR,1*U_MILLIS_PER_HOUR,140742,7 }; const int32_t GregorianCalendar::kMaxValues[] = { - 1,144683,11,53,6,31,366,7,6,1,11,23,59,59,999,12*U_MILLIS_PER_HOUR,1*U_MILLIS_PER_HOUR + 1,144683,11,53,6,31,366,7,6,1,11,23,59,59,999,12*U_MILLIS_PER_HOUR,1*U_MILLIS_PER_HOUR, 144683,7 }; char GregorianCalendar::fgClassID = 0; // Value is irrelevant @@ -386,7 +390,7 @@ GregorianCalendar::timeToFields(UDate theTime, bool_t quick, UErrorCode& status) return; int32_t rawYear; - int32_t year, month, date, dayOfWeek, dayOfYear, era; + int32_t year, yearOfWeekOfYear, month, date, dayOfWeek, locDayOfWeek, dayOfYear, era; bool_t isLeap; // Compute the year, month, and day of month from the given millis @@ -448,6 +452,7 @@ GregorianCalendar::timeToFields(UDate theTime, bool_t quick, UErrorCode& status) // Normalize day of week dayOfWeek += (dayOfWeek < 0) ? (SUNDAY+7) : SUNDAY; + era = AD; year = rawYear; @@ -456,6 +461,9 @@ GregorianCalendar::timeToFields(UDate theTime, bool_t quick, UErrorCode& status) year = 1 - year; } + // Calculate year of week of year + + internalSet(ERA, era); internalSet(YEAR, year); internalSet(MONTH, month + JANUARY); // 0-based @@ -465,6 +473,8 @@ GregorianCalendar::timeToFields(UDate theTime, bool_t quick, UErrorCode& status) if (quick) return; + yearOfWeekOfYear = year; + // Compute the week of the year. Valid week numbers run from 1 to 52 // or 53, depending on the year, the first day of the week, and the // minimal days in the first week. Days at the start of the year may @@ -483,17 +493,29 @@ GregorianCalendar::timeToFields(UDate theTime, bool_t quick, UErrorCode& status) if (lastRelDow < 0) lastRelDow += 7; if (dayOfYear > 359 && // Fast check which eliminates most cases (6 - lastRelDow) >= getMinimalDaysInFirstWeek() && - (dayOfYear + 7 - relDow) > lastDoy) woy = 1; + (dayOfYear + 7 - relDow) > lastDoy) { + woy = 1; + yearOfWeekOfYear++; + } } else if (woy == 0) { // We are the last week of the previous year. int32_t prevDoy = dayOfYear + yearLength(rawYear - 1); woy = weekNumber(prevDoy, dayOfWeek); + yearOfWeekOfYear--; } + + internalSet(WEEK_OF_YEAR, woy); + internalSet(YEAR_WOY, yearOfWeekOfYear); internalSet(WEEK_OF_MONTH, weekNumber(date, dayOfWeek)); internalSet(DAY_OF_WEEK_IN_MONTH, (date-1) / 7 + 1); + + // Calculate localized day of week + locDayOfWeek = dayOfWeek-getFirstDayOfWeek()+1; + locDayOfWeek += (locDayOfWeek<1?7:0); + internalSet(DOW_LOCAL, locDayOfWeek); } // ------------------------------------- diff --git a/icu4c/source/i18n/smpdtfmt.cpp b/icu4c/source/i18n/smpdtfmt.cpp index 627ef8298d8..89e5ef56ef5 100644 --- a/icu4c/source/i18n/smpdtfmt.cpp +++ b/icu4c/source/i18n/smpdtfmt.cpp @@ -27,6 +27,7 @@ * 02/22/99 stephen Removed character literals for EBCDIC safety * 10/14/99 aliu Updated 2-digit year parsing so that only "00" thru * "99" are recognized. {j28 4182066} +* 11/15/99 weiv Added support for week of year/day of week format ******************************************************************************** */ @@ -478,7 +479,8 @@ SimpleDateFormat::fgPatternIndexToCalendarField[] = Calendar::SECOND, Calendar::MILLISECOND, Calendar::DAY_OF_WEEK, Calendar::DAY_OF_YEAR, Calendar::DAY_OF_WEEK_IN_MONTH, Calendar::WEEK_OF_YEAR, Calendar::WEEK_OF_MONTH, - Calendar::AM_PM, Calendar::HOUR, Calendar::HOUR, Calendar::ZONE_OFFSET + Calendar::AM_PM, Calendar::HOUR, Calendar::HOUR, Calendar::ZONE_OFFSET, + Calendar::YEAR_WOY, Calendar::DOW_LOCAL }; // Map index into pattern character string to DateFormat field number @@ -492,7 +494,8 @@ SimpleDateFormat::fgPatternIndexToDateFormatField[] = { DateFormat::kDayOfWeekInMonthField, DateFormat::kWeekOfYearField, DateFormat::kWeekOfMonthField, DateFormat::kAmPmField, DateFormat::kHour1Field, DateFormat::kHour0Field, - DateFormat::kTimezoneField, + DateFormat::kTimezoneField, DateFormat::kYearWOYField, + DateFormat::kDOWLocalField }; @@ -534,6 +537,7 @@ SimpleDateFormat::subFormat(UnicodeString& result, // for "yyyy", write out the whole year; for "yy", write out the last 2 digits case kYearField: + case kYearWOYField: if (count >= 4) zeroPaddingNumber(result, value, 4, maxIntCount); else @@ -648,6 +652,7 @@ SimpleDateFormat::subFormat(UnicodeString& result, // case kWeekOfYearField: // case kWeekOfMonthField: // case kHour0Field: + // case kDOWLocalField: zeroPaddingNumber(result, value, count, maxIntCount); break; }