1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 359d709d503bab6e2b61931737e662dd293b40578ccornelius* Copyright (C) 1997-2013, International Business Machines Corporation and 459d709d503bab6e2b61931737e662dd293b40578ccornelius* others. All Rights Reserved. 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File GREGOCAL.CPP 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History: 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Description 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 02/05/97 clhuang Creation. 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 03/28/97 aliu Made highly questionable fix to computeFields to 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* handle DST correctly. 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 04/22/97 aliu Cleaned up code drastically. Added monthLength(). 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Finished unimplemented parts of computeTime() for 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* week-based date determination. Removed quetionable 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* fix and wrote correct fix for computeFields() and 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* daylight time handling. Rewrote inDaylightTime() 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* and computeFields() to handle sensitive Daylight to 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Standard time transitions correctly. 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 05/08/97 aliu Added code review changes. Fixed isLeapYear() to 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* not cutover. 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 08/12/97 aliu Added equivalentTo. Misc other fixes. Updated 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* add() from Java source. 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 07/28/98 stephen Sync up with JDK 1.2 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 09/14/98 stephen Changed type of kOneDay, kOneWeek to double. 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Fixed bug in roll() 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 10/15/99 aliu Fixed j31, incorrect WEEK_OF_YEAR computation. 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 10/15/99 aliu Fixed j32, cannot set date to Feb 29 2000 AD. 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* {JDK bug 4210209 4209272} 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11/15/99 weiv Added YEAR_WOY and DOW_LOCAL computation 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* to timeToFields method, updated kMinValues, kMaxValues & kLeastMaxValues 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 12/09/99 aliu Fixed j81, calculation errors and roll bugs 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* in year of cutover. 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 01/24/2000 aliu Revised computeJulianDay for YEAR YEAR_WOY WOY. 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************** 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <float.h> 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/gregocal.h" 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "gregoimp.h" 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h" 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h" 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ***************************************************************************** 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// class GregorianCalendar 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ***************************************************************************** 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Note that the Julian date used here is not a true Julian date, since 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* it is measured from midnight, not noon. This value is the Julian 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* day number of January 1, 1970 (Gregorian calendar) at noon UTC. [LIU] 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 60c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const int16_t kNumDays[] 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru= {0,31,59,90,120,151,181,212,243,273,304,334}; // 0-based, for day-in-year 62c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const int16_t kLeapNumDays[] 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru= {0,31,60,91,121,152,182,213,244,274,305,335}; // 0-based, for day-in-year 64c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const int8_t kMonthLength[] 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru= {31,28,31,30,31,30,31,31,30,31,30,31}; // 0-based 66c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const int8_t kLeapMonthLength[] 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru= {31,29,31,30,31,30,31,31,30,31,30,31}; // 0-based 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// setTimeInMillis() limits the Julian day range to +/-7F000000. 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// This would seem to limit the year range to: 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ms=+183882168921600000 jd=7f000000 December 20, 5828963 AD 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ms=-184303902528000000 jd=81000000 September 20, 5838270 BC 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// HOWEVER, CalendarRegressionTest/Test4167060 shows that the actual 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// range limit on the year field is smaller (~ +/-140000). [alan 3.0] 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const int32_t kGregorianCalendarLimits[UCAL_FIELD_COUNT][4] = { 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Minimum Greatest Least Maximum 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Minimum Maximum 79c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 0, 0, 1, 1}, // ERA 80c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 1, 1, 140742, 144683}, // YEAR 81c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 0, 0, 11, 11}, // MONTH 82c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 1, 1, 52, 53}, // WEEK_OF_YEAR 83c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // WEEK_OF_MONTH 84c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 1, 1, 28, 31}, // DAY_OF_MONTH 85c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 1, 1, 365, 366}, // DAY_OF_YEAR 86c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DAY_OF_WEEK 87c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { -1, -1, 4, 5}, // DAY_OF_WEEK_IN_MONTH 88c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // AM_PM 89c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR 90c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR_OF_DAY 91c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MINUTE 92c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // SECOND 93c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECOND 94c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // ZONE_OFFSET 95c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DST_OFFSET 96c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { -140742, -140742, 140742, 144683}, // YEAR_WOY 97c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DOW_LOCAL 98c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { -140742, -140742, 140742, 144683}, // EXTENDED_YEAR 99c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // JULIAN_DAY 100c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECONDS_IN_DAY 101c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // IS_LEAP_MONTH 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <pre> 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Greatest Least 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Field name Minimum Minimum Maximum Maximum 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* ---------- ------- ------- ------- ------- 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* ERA 0 0 1 1 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* YEAR 1 1 140742 144683 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* MONTH 0 0 11 11 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* WEEK_OF_YEAR 1 1 52 53 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* WEEK_OF_MONTH 0 0 4 6 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* DAY_OF_MONTH 1 1 28 31 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* DAY_OF_YEAR 1 1 365 366 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* DAY_OF_WEEK 1 1 7 7 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* DAY_OF_WEEK_IN_MONTH -1 -1 4 5 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* AM_PM 0 0 1 1 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* HOUR 0 0 11 11 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* HOUR_OF_DAY 0 0 23 23 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* MINUTE 0 0 59 59 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* SECOND 0 0 59 59 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* MILLISECOND 0 0 999 999 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* ZONE_OFFSET -12* -12* 12* 12* 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* DST_OFFSET 0 0 1* 1* 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* YEAR_WOY 1 1 140742 144683 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* DOW_LOCAL 1 1 7 7 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* </pre> 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* (*) In units of one-hour 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL) 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h> 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(GregorianCalendar) 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 00:00:00 UTC, October 15, 1582, expressed in ms from the epoch. 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Note that only Italy and other Catholic countries actually 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// observed this cutover. Most other countries followed in 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// the next few centuries, some as late as 1928. [LIU] 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// in Java, -12219292800000L 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//const UDate GregorianCalendar::kPapalCutover = -12219292800000L; 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const uint32_t kCutoverJulianDay = 2299161; 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UDate kPapalCutover = (2299161.0 - kEpochStartAsJulianDay) * U_MILLIS_PER_DAY; 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//static const UDate kPapalCutoverJulian = (2299161.0 - kEpochStartAsJulianDay); 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::GregorianCalendar(UErrorCode& status) 15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho: Calendar(status), 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufGregorianCutover(kPapalCutover), 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582), 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufIsGregorian(TRUE), fInvertGregorian(FALSE) 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(getNow(), status); 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::GregorianCalendar(TimeZone* zone, UErrorCode& status) 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru: Calendar(zone, Locale::getDefault(), status), 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufGregorianCutover(kPapalCutover), 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582), 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufIsGregorian(TRUE), fInvertGregorian(FALSE) 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(getNow(), status); 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::GregorianCalendar(const TimeZone& zone, UErrorCode& status) 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru: Calendar(zone, Locale::getDefault(), status), 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufGregorianCutover(kPapalCutover), 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582), 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufIsGregorian(TRUE), fInvertGregorian(FALSE) 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(getNow(), status); 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::GregorianCalendar(const Locale& aLocale, UErrorCode& status) 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru: Calendar(TimeZone::createDefault(), aLocale, status), 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufGregorianCutover(kPapalCutover), 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582), 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufIsGregorian(TRUE), fInvertGregorian(FALSE) 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(getNow(), status); 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::GregorianCalendar(TimeZone* zone, const Locale& aLocale, 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode& status) 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Calendar(zone, aLocale, status), 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGregorianCutover(kPapalCutover), 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582), 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsGregorian(TRUE), fInvertGregorian(FALSE) 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(getNow(), status); 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::GregorianCalendar(const TimeZone& zone, const Locale& aLocale, 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode& status) 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Calendar(zone, aLocale, status), 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGregorianCutover(kPapalCutover), 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582), 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsGregorian(TRUE), fInvertGregorian(FALSE) 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(getNow(), status); 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::GregorianCalendar(int32_t year, int32_t month, int32_t date, 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode& status) 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Calendar(TimeZone::createDefault(), Locale::getDefault(), status), 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGregorianCutover(kPapalCutover), 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582), 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsGregorian(TRUE), fInvertGregorian(FALSE) 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_ERA, AD); 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_YEAR, year); 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MONTH, month); 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DATE, date); 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::GregorianCalendar(int32_t year, int32_t month, int32_t date, 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t hour, int32_t minute, UErrorCode& status) 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Calendar(TimeZone::createDefault(), Locale::getDefault(), status), 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGregorianCutover(kPapalCutover), 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582), 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsGregorian(TRUE), fInvertGregorian(FALSE) 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_ERA, AD); 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_YEAR, year); 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MONTH, month); 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DATE, date); 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_HOUR_OF_DAY, hour); 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MINUTE, minute); 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::GregorianCalendar(int32_t year, int32_t month, int32_t date, 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t hour, int32_t minute, int32_t second, 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode& status) 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Calendar(TimeZone::createDefault(), Locale::getDefault(), status), 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGregorianCutover(kPapalCutover), 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582), 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsGregorian(TRUE), fInvertGregorian(FALSE) 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_ERA, AD); 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_YEAR, year); 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MONTH, month); 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DATE, date); 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_HOUR_OF_DAY, hour); 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MINUTE, minute); 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_SECOND, second); 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::~GregorianCalendar() 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::GregorianCalendar(const GregorianCalendar &source) 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru: Calendar(source), 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufGregorianCutover(source.fGregorianCutover), 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufCutoverJulianDay(source.fCutoverJulianDay), fNormalizedGregorianCutover(source.fNormalizedGregorianCutover), fGregorianCutoverYear(source.fGregorianCutoverYear), 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufIsGregorian(source.fIsGregorian), fInvertGregorian(source.fInvertGregorian) 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar* GregorianCalendar::clone() const 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new GregorianCalendar(*this); 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar & 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::operator=(const GregorianCalendar &right) 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (this != &right) 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar::operator=(right); 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGregorianCutover = right.fGregorianCutover; 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fNormalizedGregorianCutover = right.fNormalizedGregorianCutover; 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGregorianCutoverYear = right.fGregorianCutoverYear; 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCutoverJulianDay = right.fCutoverJulianDay; 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool GregorianCalendar::isEquivalentTo(const Calendar& other) const 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Calendar override. 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return Calendar::isEquivalentTo(other) && 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGregorianCutover == ((GregorianCalendar*)&other)->fGregorianCutover; 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::setGregorianChange(UDate date, UErrorCode& status) 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGregorianCutover = date; 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Precompute two internal variables which we use to do the actual 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // cutover computations. These are the normalized cutover, which is the 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // midnight at or before the cutover, and the cutover year. The 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // normalized cutover is in pure date milliseconds; it contains no time 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // of day or timezone component, and it used to compare against other 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pure date values. 333b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t cutoverDay = (int32_t)ClockMath::floorDivide(fGregorianCutover, (double)kOneDay); 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fNormalizedGregorianCutover = cutoverDay * kOneDay; 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Handle the rare case of numeric overflow. If the user specifies a 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // change of UDate(Long.MIN_VALUE), in order to get a pure Gregorian 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // calendar, then the epoch day is -106751991168, which when multiplied 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // by ONE_DAY gives 9223372036794351616 -- the negative value is too 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // large for 64 bits, and overflows into a positive value. We correct 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // this by using the next day, which for all intents is semantically 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // equivalent. 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cutoverDay < 0 && fNormalizedGregorianCutover > 0) { 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fNormalizedGregorianCutover = (cutoverDay + 1) * kOneDay; 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Normalize the year so BC values are represented as 0 and negative 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // values. 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru GregorianCalendar *cal = new GregorianCalendar(getTimeZone(), status); 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* test for NULL */ 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cal == 0) { 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cal->setTime(date, status); 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGregorianCutoverYear = cal->get(UCAL_YEAR, status); 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cal->get(UCAL_ERA, status) == BC) 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGregorianCutoverYear = 1 - fGregorianCutoverYear; 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCutoverJulianDay = cutoverDay; 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete cal; 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid GregorianCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status) { 36754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t eyear, month, dayOfMonth, dayOfYear, unusedRemainder; 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: jd%d- (greg's %d)- [cut=%d]\n", 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, julianDay, getGregorianDayOfYear(), fCutoverJulianDay); 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (julianDay >= fCutoverJulianDay) { 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru month = getGregorianMonth(); 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayOfMonth = getGregorianDayOfMonth(); 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayOfYear = getGregorianDayOfYear(); 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eyear = getGregorianYear(); 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The Julian epoch day (not the same as Julian Day) 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is zero on Saturday December 30, 0 (Gregorian). 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t julianEpochDay = julianDay - (kJan1_1JulianDay - 2); 38954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius eyear = (int32_t) ClockMath::floorDivide((4.0*julianEpochDay) + 1464.0, (int32_t) 1461, unusedRemainder); 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Compute the Julian calendar day number for January 1, eyear 392b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t january1 = 365*(eyear-1) + ClockMath::floorDivide(eyear-1, (int32_t)4); 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayOfYear = (julianEpochDay - january1); // 0-based 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Julian leap years occurred historically every 4 years starting 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // with 8 AD. Before 8 AD the spacing is irregular; every 3 years 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // from 45 BC to 9 BC, and then none until 8 AD. However, we don't 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // implement this historical detail; instead, we implement the 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // computatinally cleaner proleptic calendar, which assumes 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // consistent 4-year cycles throughout time. 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool isLeap = ((eyear&0x3) == 0); // equiv. to (eyear%4 == 0) 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Common Julian/Gregorian calculation 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t correction = 0; 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t march1 = isLeap ? 60 : 59; // zero-based DOY for March 1 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dayOfYear >= march1) { 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru correction = isLeap ? 1 : 2; 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru month = (12 * (dayOfYear + correction) + 6) / 367; // zero-based month 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayOfMonth = dayOfYear - (isLeap?kLeapNumDays[month]:kNumDays[month]) + 1; // one-based DOM 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++dayOfYear; 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fprintf(stderr, "%d - %d[%d] + 1\n", dayOfYear, isLeap?kLeapNumDays[month]:kNumDays[month], month ); 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fprintf(stderr, "%s:%d: greg's HCF %d -> %d/%d/%d not %d/%d/%d\n", 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // __FILE__, __LINE__,julianDay, 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // eyear,month,dayOfMonth, 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // getGregorianYear(), getGregorianMonth(), getGregorianDayOfMonth() ); 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: doy %d (greg's %d)- [cut=%d]\n", 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, dayOfYear, getGregorianDayOfYear(), fCutoverJulianDay); 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // [j81] if we are after the cutover in its year, shift the day of the year 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((eyear == fGregorianCutoverYear) && (julianDay >= fCutoverJulianDay)) { 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //from handleComputeMonthStart 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t gregShift = Grego::gregorianShift(eyear); 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: gregorian shift %d ::: doy%d => %d [cut=%d]\n", 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__,gregShift, dayOfYear, dayOfYear+gregShift, fCutoverJulianDay); 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayOfYear += gregShift; 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_MONTH, month); 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_DAY_OF_MONTH, dayOfMonth); 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_DAY_OF_YEAR, dayOfYear); 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_EXTENDED_YEAR, eyear); 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t era = AD; 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (eyear < 1) { 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru era = BC; 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eyear = 1 - eyear; 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_ERA, era); 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_YEAR, eyear); 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUDate 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::getGregorianChange() const 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fGregorianCutover; 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::isLeapYear(int32_t year) const 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // MSVC complains bitterly if we try to use Grego::isLeapYear here 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // NOTE: year&0x3 == year%4 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (year >= fGregorianCutoverYear ? 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (((year&0x3) == 0) && ((year%100 != 0) || (year%400 == 0))) : // Gregorian 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((year&0x3) == 0)); // Julian 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t GregorianCalendar::handleComputeJulianDay(UCalendarDateFields bestField) 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fInvertGregorian = FALSE; 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t jd = Calendar::handleComputeJulianDay(bestField); 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((bestField == UCAL_WEEK_OF_YEAR) && // if we are doing WOY calculations, we are counting relative to Jan 1 *julian* 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (internalGet(UCAL_EXTENDED_YEAR)==fGregorianCutoverYear) && 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jd >= fCutoverJulianDay) { 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fInvertGregorian = TRUE; // So that the Julian Jan 1 will be used in handleComputeMonthStart 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return Calendar::handleComputeJulianDay(bestField); 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The following check handles portions of the cutover year BEFORE the 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // cutover itself happens. 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //if ((fIsGregorian==TRUE) != (jd >= fCutoverJulianDay)) { /* cutoverJulianDay)) { */ 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((fIsGregorian==TRUE) != (jd >= fCutoverJulianDay)) { /* cutoverJulianDay)) { */ 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: jd [invert] %d\n", 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, jd); 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fInvertGregorian = TRUE; 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jd = Calendar::handleComputeJulianDay(bestField); 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: fIsGregorian %s, fInvertGregorian %s - ", 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__,fIsGregorian?"T":"F", fInvertGregorian?"T":"F"); 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " jd NOW %d\n", 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jd); 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: jd [==] %d - %sfIsGregorian %sfInvertGregorian, %d\n", 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, jd, fIsGregorian?"T":"F", fInvertGregorian?"T":"F", bestField); 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fIsGregorian && (internalGet(UCAL_EXTENDED_YEAR) == fGregorianCutoverYear)) { 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t gregShift = Grego::gregorianShift(internalGet(UCAL_EXTENDED_YEAR)); 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bestField == UCAL_DAY_OF_YEAR) { 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: [DOY%d] gregorian shift of JD %d += %d\n", 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, fFields[bestField],jd, gregShift); 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jd -= gregShift; 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if ( bestField == UCAL_WEEK_OF_MONTH ) { 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t weekShift = 14; 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: [WOY/WOM] gregorian week shift of %d += %d\n", 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, jd, weekShift); 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jd += weekShift; // shift by weeks for week based fields. 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return jd; 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t GregorianCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool /* useMonth */) const 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru GregorianCalendar *nonConstThis = (GregorianCalendar*)this; // cast away const 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If the month is out of range, adjust it into range, and 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // modify the extended year value accordingly. 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (month < 0 || month > 11) { 538b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru eyear += ClockMath::floorDivide(month, 12, month); 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool isLeap = eyear%4 == 0; 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t y = eyear-1; 543b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t julianDay = 365*y + ClockMath::floorDivide(y, 4) + (kJan1_1JulianDay - 3); 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nonConstThis->fIsGregorian = (eyear >= fGregorianCutoverYear); 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: (hcms%d/%d) fIsGregorian %s, fInvertGregorian %s\n", 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, eyear,month, fIsGregorian?"T":"F", fInvertGregorian?"T":"F"); 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fInvertGregorian) { 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nonConstThis->fIsGregorian = !fIsGregorian; 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fIsGregorian) { 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isLeap = isLeap && ((eyear%100 != 0) || (eyear%400 == 0)); 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Add 2 because Gregorian calendar starts 2 days after 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Julian calendar 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t gregShift = Grego::gregorianShift(eyear); 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: (hcms%d/%d) gregorian shift of %d += %d\n", 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, eyear, month, julianDay, gregShift); 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru julianDay += gregShift; 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // At this point julianDay indicates the day BEFORE the first 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // day of January 1, <eyear> of either the Julian or Gregorian 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // calendar. 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (month != 0) { 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru julianDay += isLeap?kLeapNumDays[month]:kNumDays[month]; 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return julianDay; 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t GregorianCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If the month is out of range, adjust it into range, and 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // modify the extended year value accordingly. 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (month < 0 || month > 11) { 581b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru extendedYear += ClockMath::floorDivide(month, 12, month); 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return isLeapYear(extendedYear) ? kLeapMonthLength[month] : kMonthLength[month]; 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t GregorianCalendar::handleGetYearLength(int32_t eyear) const { 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return isLeapYear(eyear) ? 366 : 365; 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::monthLength(int32_t month) const 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t year = internalGet(UCAL_EXTENDED_YEAR); 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return handleGetMonthLength(year, month); 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::monthLength(int32_t month, int32_t year) const 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return isLeapYear(year) ? kLeapMonthLength[month] : kMonthLength[month]; 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::yearLength(int32_t year) const 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return isLeapYear(year) ? 366 : 365; 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::yearLength() const 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return isLeapYear(internalGet(UCAL_YEAR)) ? 366 : 365; 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* After adjustments such as add(MONTH), add(YEAR), we don't want the 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* month to jump around. E.g., we don't want Jan 31 + 1 month to go to Mar 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 3, we want it to go to Feb 28. Adjustments which might run into this 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* problem call this method to retain the proper month. 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::pinDayOfMonth() 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t monthLen = monthLength(internalGet(UCAL_MONTH)); 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dom = internalGet(UCAL_DATE); 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(dom > monthLen) 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DATE, monthLen); 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::validateFields() const 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t field = 0; field < UCAL_FIELD_COUNT; field++) { 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Ignore DATE and DAY_OF_YEAR which are handled below 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (field != UCAL_DATE && 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru field != UCAL_DAY_OF_YEAR && 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isSet((UCalendarDateFields)field) && 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ! boundsCheck(internalGet((UCalendarDateFields)field), (UCalendarDateFields)field)) 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Values differ in Least-Maximum and Maximum should be handled 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // specially. 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isSet(UCAL_DATE)) { 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t date = internalGet(UCAL_DATE); 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (date < getMinimum(UCAL_DATE) || 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru date > monthLength(internalGet(UCAL_MONTH))) { 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isSet(UCAL_DAY_OF_YEAR)) { 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t days = internalGet(UCAL_DAY_OF_YEAR); 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (days < 1 || days > yearLength()) { 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Handle DAY_OF_WEEK_IN_MONTH, which must not have the value zero. 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We've checked against minimum and maximum above already. 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isSet(UCAL_DAY_OF_WEEK_IN_MONTH) && 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0 == internalGet(UCAL_DAY_OF_WEEK_IN_MONTH)) { 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::boundsCheck(int32_t value, UCalendarDateFields field) const 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return value >= getMinimum(field) && value <= getMaximum(field); 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUDate 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::getEpochDay(UErrorCode& status) 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru complete(status); 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Divide by 1000 (convert to seconds) in order to prevent overflow when 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // dealing with UDate(Long.MIN_VALUE) and UDate(Long.MAX_VALUE). 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double wallSec = internalGetTime()/1000 + (internalGet(UCAL_ZONE_OFFSET) + internalGet(UCAL_DST_OFFSET))/1000; 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 700b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return ClockMath::floorDivide(wallSec, kOneDay/1000.0); 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Compute the julian day number of the day BEFORE the first day of 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* January 1, year 1 of the given calendar. If julianDay == 0, it 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* or Gregorian). 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querudouble GregorianCalendar::computeJulianDayOfYear(UBool isGregorian, 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t year, UBool& isLeap) 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isLeap = year%4 == 0; 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t y = year - 1; 719b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru double julianDay = 365.0*y + ClockMath::floorDivide(y, 4) + (kJan1_1JulianDay - 3); 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isGregorian) { 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isLeap = isLeap && ((year%100 != 0) || (year%400 == 0)); 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Add 2 because Gregorian calendar starts 2 days after Julian calendar 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru julianDay += Grego::gregorianShift(year); 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return julianDay; 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// /** 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// * Compute the day of week, relative to the first day of week, from 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// * 0..6, of the current DOW_LOCAL or DAY_OF_WEEK fields. This is 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// * equivalent to get(DOW_LOCAL) - 1. 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// */ 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// int32_t GregorianCalendar::computeRelativeDOW() const { 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// int32_t relDow = 0; 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// if (fStamp[UCAL_DOW_LOCAL] > fStamp[UCAL_DAY_OF_WEEK]) { 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// relDow = internalGet(UCAL_DOW_LOCAL) - 1; // 1-based 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// } else if (fStamp[UCAL_DAY_OF_WEEK] != kUnset) { 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// relDow = internalGet(UCAL_DAY_OF_WEEK) - getFirstDayOfWeek(); 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// if (relDow < 0) relDow += 7; 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// } 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// return relDow; 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// } 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// /** 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// * Compute the day of week, relative to the first day of week, 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// * from 0..6 of the given julian day. 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// */ 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// int32_t GregorianCalendar::computeRelativeDOW(double julianDay) const { 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// int32_t relDow = julianDayToDayOfWeek(julianDay) - getFirstDayOfWeek(); 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// if (relDow < 0) { 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// relDow += 7; 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// } 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// return relDow; 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// } 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// /** 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// * Compute the DOY using the WEEK_OF_YEAR field and the julian day 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// * of the day BEFORE January 1 of a year (a return value from 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// * computeJulianDayOfYear). 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// */ 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// int32_t GregorianCalendar::computeDOYfromWOY(double julianDayOfYear) const { 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// // Compute DOY from day of week plus week of year 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// // Find the day of the week for the first of this year. This 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// // is zero-based, with 0 being the locale-specific first day of 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// // the week. Add 1 to get first day of year. 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// int32_t fdy = computeRelativeDOW(julianDayOfYear + 1); 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// return 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// // Compute doy of first (relative) DOW of WOY 1 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// (((7 - fdy) < getMinimalDaysInFirstWeek()) 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ? (8 - fdy) : (1 - fdy)) 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// // Adjust for the week number. 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// + (7 * (internalGet(UCAL_WEEK_OF_YEAR) - 1)) 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// // Adjust for the DOW 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// + computeRelativeDOW(); 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// } 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querudouble 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::millisToJulianDay(UDate millis) 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 788b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return (double)kEpochStartAsJulianDay + ClockMath::floorDivide(millis, (double)kOneDay); 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUDate 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::julianDayToMillis(double julian) 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (UDate) ((julian - kEpochStartAsJulianDay) * (double) kOneDay); 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::aggregateStamp(int32_t stamp_a, int32_t stamp_b) 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (((stamp_a != kUnset && stamp_b != kUnset) 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ? uprv_max(stamp_a, stamp_b) 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : (int32_t)kUnset)); 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Roll a field by a signed amount. 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Note: This will be made public later. [LIU] 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::roll(EDateFields field, int32_t amount, UErrorCode& status) { 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru roll((UCalendarDateFields) field, amount, status); 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::roll(UCalendarDateFields field, int32_t amount, UErrorCode& status) 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((amount == 0) || U_FAILURE(status)) { 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // J81 processing. (gregorian cutover) 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool inCutoverMonth = FALSE; 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t cMonthLen=0; // 'c' for cutover; in days 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t cDayOfMonth=0; // no discontinuity: [0, cMonthLen) 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double cMonthStart=0.0; // in ms 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Common code - see if we're in the cutover month of the cutover year 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(get(UCAL_EXTENDED_YEAR, status) == fGregorianCutoverYear) { 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (field) { 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_MONTH: 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_WEEK_OF_MONTH: 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t max = monthLength(internalGet(UCAL_MONTH)); 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UDate t = internalGetTime(); 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We subtract 1 from the DAY_OF_MONTH to make it zero-based, and an 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // additional 10 if we are after the cutover. Thus the monthStart 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // value will be correct iff we actually are in the cutover month. 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cDayOfMonth = internalGet(UCAL_DAY_OF_MONTH) - ((t >= fGregorianCutover) ? 10 : 0); 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cMonthStart = t - ((cDayOfMonth - 1) * kOneDay); 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // A month containing the cutover is 10 days shorter. 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((cMonthStart < fGregorianCutover) && 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (cMonthStart + (cMonthLen=(max-10))*kOneDay >= fGregorianCutover)) { 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inCutoverMonth = TRUE; 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ; 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (field) { 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_WEEK_OF_YEAR: { 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Unlike WEEK_OF_MONTH, WEEK_OF_YEAR never shifts the day of the 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // week. Also, rolling the week of the year can have seemingly 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // strange effects simply because the year of the week of year 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // may be different from the calendar year. For example, the 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // date Dec 28, 1997 is the first day of week 1 of 1998 (if 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // weeks start on Sunday and the minimal days in first week is 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // <= 3). 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t woy = get(UCAL_WEEK_OF_YEAR, status); 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the ISO year, which matches the week of year. This 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // may be one year before or after the calendar year. 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t isoYear = get(UCAL_YEAR_WOY, status); 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t isoDoy = internalGet(UCAL_DAY_OF_YEAR); 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (internalGet(UCAL_MONTH) == UCAL_JANUARY) { 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (woy >= 52) { 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isoDoy += handleGetYearLength(isoYear); 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (woy == 1) { 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isoDoy -= handleGetYearLength(isoYear - 1); 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru woy += amount; 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Do fast checks to avoid unnecessary computation: 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (woy < 1 || woy > 52) { 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Determine the last week of the ISO year. 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We do this using the standard formula we use 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // everywhere in this file. If we can see that the 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // days at the end of the year are going to fall into 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // week 1 of the next year, we drop the last week by 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // subtracting 7 from the last day of the year. 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t lastDoy = handleGetYearLength(isoYear); 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t lastRelDow = (lastDoy - isoDoy + internalGet(UCAL_DAY_OF_WEEK) - 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getFirstDayOfWeek()) % 7; 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lastRelDow < 0) lastRelDow += 7; 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((6 - lastRelDow) >= getMinimalDaysInFirstWeek()) lastDoy -= 7; 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t lastWoy = weekNumber(lastDoy, lastRelDow + 1); 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru woy = ((woy + lastWoy - 1) % lastWoy) + 1; 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_WEEK_OF_YEAR, woy); 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_YEAR_WOY,isoYear); 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_MONTH: 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( !inCutoverMonth ) { 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar::roll(field, amount, status); 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // [j81] 1582 special case for DOM 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The default computation works except when the current month 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // contains the Gregorian cutover. We handle this special case 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // here. [j81 - aliu] 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double monthLen = cMonthLen * kOneDay; 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double msIntoMonth = uprv_fmod(internalGetTime() - cMonthStart + 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru amount * kOneDay, monthLen); 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msIntoMonth < 0) { 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msIntoMonth += monthLen; 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: roll DOM %d -> %.0lf ms \n", 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__,amount, cMonthLen, cMonthStart+msIntoMonth); 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(cMonthStart + msIntoMonth, status); 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_WEEK_OF_MONTH: 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( !inCutoverMonth ) { 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar::roll(field, amount, status); 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: roll WOM %d ??????????????????? \n", 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__,amount); 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // NOTE: following copied from the old 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // GregorianCalendar::roll( WEEK_OF_MONTH ) code 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // This is tricky, because during the roll we may have to shift 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to a different day of the week. For example: 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // s m t w r f s 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1 2 3 4 5 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 6 7 8 9 10 11 12 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // When rolling from the 6th or 7th back one week, we go to the 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1st (assuming that the first partial week counts). The same 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // thing happens at the end of the month. 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The other tricky thing is that we have to figure out whether 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the first partial week actually counts or not, based on the 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // minimal first days in the week. And we have to use the 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // correct first day of the week to delineate the week 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // boundaries. 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Here's our algorithm. First, we find the real boundaries of 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the month. Then we discard the first partial week if it 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // doesn't count in this locale. Then we fill in the ends with 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // phantom days, so that the first partial week and the last 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // partial week are full weeks. We then have a nice square 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // block of weeks. We do the usual rolling within this block, 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // as is done elsewhere in this method. If we wind up on one of 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the phantom days that we added, we recognize this and pin to 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the first or the last day of the month. Easy, eh? 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Another wrinkle: To fix jitterbug 81, we have to make all this 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // work in the oddball month containing the Gregorian cutover. 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // This month is 10 days shorter than usual, and also contains 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // a discontinuity in the days; e.g., the default cutover month 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is Oct 1582, and goes from day of month 4 to day of month 15. 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Normalize the DAY_OF_WEEK so that 0 is the first day of the week 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // in this locale. We have dow in 0..6. 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dow = internalGet(UCAL_DAY_OF_WEEK) - getFirstDayOfWeek(); 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dow < 0) 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dow += 7; 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find the day of month, compensating for cutover discontinuity. 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dom = cDayOfMonth; 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find the day of the week (normalized for locale) for the first 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // of the month. 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t fdm = (dow - dom + 1) % 7; 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fdm < 0) 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fdm += 7; 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the first day of the first full week of the month, 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // including phantom days, if any. Figure out if the first week 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // counts or not; if it counts, then fill in phantom days. If 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // not, advance to the first real full week (skip the partial week). 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start; 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((7 - fdm) < getMinimalDaysInFirstWeek()) 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = 8 - fdm; // Skip the first partial week 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = 1 - fdm; // This may be zero or negative 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the day of the week (normalized for locale) for the last 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // day of the month. 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t monthLen = cMonthLen; 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t ldm = (monthLen - dom + dow) % 7; 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here. 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the limit day for the blocked-off rectangular month; that 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is, the day which is one past the last day of the month, 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // after the month has already been filled in with phantom days 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to fill out the last week. This day has a normalized DOW of 0. 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit = monthLen + 7 - ldm; 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Now roll between start and (limit - 1). 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t gap = limit - start; 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t newDom = (dom + amount*7 - start) % gap; 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (newDom < 0) 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newDom += gap; 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newDom += start; 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Finally, pin to the real start and end of the month. 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (newDom < 1) 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newDom = 1; 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (newDom > monthLen) 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newDom = monthLen; 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Set the DAY_OF_MONTH. We rely on the fact that this field 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // takes precedence over everything else (since all other fields 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // are also set at this point). If this fact changes (if the 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // disambiguation algorithm changes) then we will have to unset 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the appropriate fields here so that DAY_OF_MONTH is attended 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to. 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If we are in the cutover month, manipulate ms directly. Don't do 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // this in general because it doesn't work across DST boundaries 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // (details, details). This takes care of the discontinuity. 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(cMonthStart + (newDom-1)*kOneDay, status); 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar::roll(field, amount, status); 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Return the minimum value that this field could have, given the current date. 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum(). 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @param field the time field. 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @return the minimum value that this field could have, given the current date. 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @deprecated ICU 2.6. Use getActualMinimum(UCalendarDateFields field) instead. 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t GregorianCalendar::getActualMinimum(EDateFields field) const 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getMinimum((UCalendarDateFields)field); 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t GregorianCalendar::getActualMinimum(EDateFields field, UErrorCode& /* status */) const 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getMinimum((UCalendarDateFields)field); 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Return the minimum value that this field could have, given the current date. 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum(). 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @param field the time field. 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @return the minimum value that this field could have, given the current date. 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @draft ICU 2.6. 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t GregorianCalendar::getActualMinimum(UCalendarDateFields field, UErrorCode& /* status */) const 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getMinimum(field); 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------ 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Old year limits were least max 292269054, max 292278994. 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @stable ICU 2.0 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t GregorianCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const { 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return kGregorianCalendarLimits[field][limitType]; 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Return the maximum value that this field could have, given the current date. 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* maximum would be 28; for "Feb 3, 1996" it s 29. Similarly for a Hebrew calendar, 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* for some years the actual maximum for MONTH is 12, and for others 13. 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @stable ICU 2.0 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t GregorianCalendar::getActualMaximum(UCalendarDateFields field, UErrorCode& status) const 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* It is a known limitation that the code here (and in getActualMinimum) 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * won't behave properly at the extreme limits of GregorianCalendar's 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * representable range (except for the code that handles the YEAR 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * field). That's because the ends of the representable range are at 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * odd spots in the year. For calendars with the default Gregorian 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * cutover, these limits are Sun Dec 02 16:47:04 GMT 292269055 BC to Sun 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Aug 17 07:12:55 GMT 292278994 AD, somewhat different for non-GMT 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * zones. As a result, if the calendar is set to Aug 1 292278994 AD, 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the actual maximum of DAY_OF_MONTH is 17, not 30. If the date is Mar 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 31 in that year, the actual maximum month might be Jul, whereas is 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the date is Mar 15, the actual maximum might be Aug -- depending on 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the precise semantics that are desired. Similar considerations 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * affect all fields. Nonetheless, this effect is sufficiently arcane 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that we permit it, rather than complicating the code to handle such 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * intricacies. - liu 8/20/98 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * UPDATE: No longer true, since we have pulled in the limit values on 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the year. - Liu 11/6/00 */ 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (field) { 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_YEAR: 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* The year computation is no different, in principle, from the 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * others, however, the range of possible maxima is large. In 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * addition, the way we know we've exceeded the range is different. 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * For these reasons, we use the special case code below to handle 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * this field. 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The actual maxima for YEAR depend on the type of calendar: 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Gregorian = May 17, 292275056 BC - Aug 17, 292278994 AD 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Julian = Dec 2, 292269055 BC - Jan 3, 292272993 AD 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Hybrid = Dec 2, 292269055 BC - Aug 17, 292278994 AD 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We know we've exceeded the maximum when either the month, date, 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * time, or era changes in response to setting the year. We don't 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * check for month, date, and time here because the year and era are 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * sufficient to detect an invalid year setting. NOTE: If code is 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * added to check the month and date in the future for some reason, 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Feb 29 must be allowed to shift to Mar 1 when setting the year. 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) return 0; 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar *cal = clone(); 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!cal) { 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cal->setLenient(TRUE); 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t era = cal->get(UCAL_ERA, status); 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UDate d = cal->getTime(status); 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Perform a binary search, with the invariant that lowGood is a 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * valid year, and highBad is an out of range year. 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t lowGood = kGregorianCalendarLimits[UCAL_YEAR][1]; 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t highBad = kGregorianCalendarLimits[UCAL_YEAR][2]+1; 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while ((lowGood + 1) < highBad) { 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t y = (lowGood + highBad) / 2; 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cal->set(UCAL_YEAR, y); 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cal->get(UCAL_YEAR, status) == y && cal->get(UCAL_ERA, status) == era) { 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lowGood = y; 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru highBad = y; 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cal->setTime(d, status); // Restore original fields 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete cal; 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return lowGood; 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return Calendar::getActualMaximum(field,status); 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t GregorianCalendar::handleGetExtendedYear() { 117750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // the year to return 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t year = kEpochYear; 117950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 118050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // year field to use 118150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t yearField = UCAL_EXTENDED_YEAR; 118250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 118350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // There are three separate fields which could be used to 118450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // derive the proper year. Use the one most recently set. 118550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (fStamp[yearField] < fStamp[UCAL_YEAR]) 118650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho yearField = UCAL_YEAR; 118750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (fStamp[yearField] < fStamp[UCAL_YEAR_WOY]) 118850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho yearField = UCAL_YEAR_WOY; 118950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 119050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // based on the "best" year field, get the year 119150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(yearField) { 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_EXTENDED_YEAR: 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru year = internalGet(UCAL_EXTENDED_YEAR, kEpochYear); 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_YEAR: 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The year defaults to the epoch start, the era to AD 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t era = internalGet(UCAL_ERA, AD); 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (era == BC) { 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru year = 1 - internalGet(UCAL_YEAR, 1); // Convert to extended year 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru year = internalGet(UCAL_YEAR, kEpochYear); 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_YEAR_WOY: 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru year = handleGetExtendedYearFromWeekFields(internalGet(UCAL_YEAR_WOY), internalGet(UCAL_WEEK_OF_YEAR)); 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if(internalGet(UCAL_YEAR_WOY) != year) { 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: hGEYFWF[%d,%d] -> %d\n", 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__,internalGet(UCAL_YEAR_WOY),internalGet(UCAL_WEEK_OF_YEAR),year); 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //} 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru year = kEpochYear; 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return year; 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t GregorianCalendar::handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t woy) 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // convert year to extended form 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t era = internalGet(UCAL_ERA, AD); 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(era == BC) { 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru yearWoy = 1 - yearWoy; 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return Calendar::handleGetExtendedYearFromWeekFields(yearWoy, woy); 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::inDaylightTime(UErrorCode& status) const 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status) || !getTimeZone().useDaylightTime()) 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Force an update of the state of the Calendar. 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((GregorianCalendar*)this)->complete(status); // cast away const 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE); 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Return the ERA. We need a special method for this because the 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* default ERA is AD, but a zero (unset) ERA is BC. 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::internalGetEra() const { 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return isSet(UCAL_ERA) ? internalGet(UCAL_ERA) : (int32_t)AD; 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGregorianCalendar::getType() const { 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //static const char kGregorianType = "gregorian"; 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return "gregorian"; 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 126759d709d503bab6e2b61931737e662dd293b40578ccornelius/** 126859d709d503bab6e2b61931737e662dd293b40578ccornelius * The system maintains a static default century start date and Year. They are 126959d709d503bab6e2b61931737e662dd293b40578ccornelius * initialized the first time they are used. Once the system default century date 127059d709d503bab6e2b61931737e662dd293b40578ccornelius * and year are set, they do not change. 127159d709d503bab6e2b61931737e662dd293b40578ccornelius */ 127259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic UDate gSystemDefaultCenturyStart = DBL_MIN; 127359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic int32_t gSystemDefaultCenturyStartYear = -1; 127459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gSystemDefaultCenturyInit = U_INITONCE_INITIALIZER; 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool GregorianCalendar::haveDefaultCentury() const 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 128259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV 128359d709d503bab6e2b61931737e662dd293b40578ccorneliusinitializeSystemDefaultCentury() 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // initialize systemDefaultCentury and systemDefaultCenturyYear based 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // on the current time. They'll be set to 80 years before 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the current time. 1288b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 128959d709d503bab6e2b61931737e662dd293b40578ccornelius GregorianCalendar calendar(status); 129059d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_SUCCESS(status)) { 129159d709d503bab6e2b61931737e662dd293b40578ccornelius calendar.setTime(Calendar::getNow(), status); 129259d709d503bab6e2b61931737e662dd293b40578ccornelius calendar.add(UCAL_YEAR, -80, status); 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 129459d709d503bab6e2b61931737e662dd293b40578ccornelius gSystemDefaultCenturyStart = calendar.getTime(status); 129559d709d503bab6e2b61931737e662dd293b40578ccornelius gSystemDefaultCenturyStartYear = calendar.get(UCAL_YEAR, status); 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1297b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // We have no recourse upon failure unless we want to propagate the failure 1298b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // out. 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 130159d709d503bab6e2b61931737e662dd293b40578ccorneliusUDate GregorianCalendar::defaultCenturyStart() const { 130259d709d503bab6e2b61931737e662dd293b40578ccornelius // lazy-evaluate systemDefaultCenturyStart 130359d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); 130459d709d503bab6e2b61931737e662dd293b40578ccornelius return gSystemDefaultCenturyStart; 130559d709d503bab6e2b61931737e662dd293b40578ccornelius} 130659d709d503bab6e2b61931737e662dd293b40578ccornelius 130759d709d503bab6e2b61931737e662dd293b40578ccorneliusint32_t GregorianCalendar::defaultCenturyStartYear() const { 130859d709d503bab6e2b61931737e662dd293b40578ccornelius // lazy-evaluate systemDefaultCenturyStartYear 130959d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); 131059d709d503bab6e2b61931737e662dd293b40578ccornelius return gSystemDefaultCenturyStartYear; 131159d709d503bab6e2b61931737e662dd293b40578ccornelius} 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */ 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//eof 1318