/*
*******************************************************************************
* Copyright (C) 1997-2004, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
* File GREGOCAL.CPP
*
* Modification History:
*
*   Date        Name        Description
*   02/05/97    clhuang     Creation.
*   03/28/97    aliu        Made highly questionable fix to computeFields to
*                           handle DST correctly.
*   04/22/97    aliu        Cleaned up code drastically.  Added monthLength().
*                           Finished unimplemented parts of computeTime() for
*                           week-based date determination.  Removed quetionable
*                           fix and wrote correct fix for computeFields() and
*                           daylight time handling.  Rewrote inDaylightTime()
*                           and computeFields() to handle sensitive Daylight to
*                           Standard time transitions correctly.
*   05/08/97    aliu        Added code review changes.  Fixed isLeapYear() to
*                           not cutover.
*   08/12/97    aliu        Added equivalentTo.  Misc other fixes.  Updated
*                           add() from Java source.
*    07/28/98    stephen        Sync up with JDK 1.2
*    09/14/98    stephen        Changed type of kOneDay, kOneWeek to double.
*                            Fixed bug in roll() 
*   10/15/99    aliu        Fixed j31, incorrect WEEK_OF_YEAR computation.
*   10/15/99    aliu        Fixed j32, cannot set date to Feb 29 2000 AD.
*                           {JDK bug 4210209 4209272}
*   11/15/99    weiv        Added YEAR_WOY and DOW_LOCAL computation
*                           to timeToFields method, updated kMinValues, kMaxValues & kLeastMaxValues
*   12/09/99    aliu        Fixed j81, calculation errors and roll bugs
*                           in year of cutover.
*   01/24/2000  aliu        Revised computeJulianDay for YEAR YEAR_WOY WOY.
********************************************************************************
*/

#include "unicode/utypes.h"
#include <float.h>

#if !UCONFIG_NO_FORMATTING

#include "unicode/gregocal.h"
#include "gregoimp.h"
#include "mutex.h"
#include "uassert.h"

// *****************************************************************************
// class GregorianCalendar
// *****************************************************************************

/**
 * Note that the Julian date used here is not a true Julian date, since
 * it is measured from midnight, not noon.  This value is the Julian
 * day number of January 1, 1970 (Gregorian calendar) at noon UTC. [LIU]
 */

static const int32_t kNumDays[]
    = {0,31,59,90,120,151,181,212,243,273,304,334}; // 0-based, for day-in-year
static const int32_t kLeapNumDays[]
    = {0,31,60,91,121,152,182,213,244,274,305,335}; // 0-based, for day-in-year
static const int32_t kMonthLength[]
    = {31,28,31,30,31,30,31,31,30,31,30,31}; // 0-based
static const int32_t kLeapMonthLength[]
    = {31,29,31,30,31,30,31,31,30,31,30,31}; // 0-based

static const int32_t kGregorianCalendarLimits[UCAL_FIELD_COUNT][4] = {
    // Minimum  Greatest    Least  Maximum
    //           Minimum  Maximum
    {        0,        0,       1,       1 }, // ERA
    {        1,        1,  140742,  144683 }, // YEAR
    {        0,        0,      11,      11 }, // MONTH
    {        1,        1,      52,      53 }, // WEEK_OF_YEAR
    {        0,        0,       4,       6 }, // WEEK_OF_MONTH
    {        1,        1,      28,      31 }, // DAY_OF_MONTH
    {        1,        1,     365,     366 }, // DAY_OF_YEAR
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1},// DAY_OF_WEEK
    {       -1,       -1,       4,       6 }, // DAY_OF_WEEK_IN_MONTH
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1},// AM_PM
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1},// HOUR
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1},// HOUR_OF_DAY
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1},// MINUTE
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1},// SECOND
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1},// MILLISECOND
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1},// ZONE_OFFSET
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1},// DST_OFFSET
    { -140742, -140742, 140742, 144683 }, // YEAR_WOY
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1},// DOW_LOCAL
    { -140742, -140742, 140742, 144683 }, // EXTENDED_YEAR
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1},// JULIAN_DAY
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1} // MILLISECONDS_IN_DAY
};

/*
 * <pre>
 *                            Greatest       Least 
 * Field name        Minimum   Minimum     Maximum     Maximum
 * ----------        -------   -------     -------     -------
 * ERA                     0         0           1           1
 * YEAR                    1         1      140742      144683
 * MONTH                   0         0          11          11
 * WEEK_OF_YEAR            1         1          52          53
 * WEEK_OF_MONTH           0         0           4           6
 * DAY_OF_MONTH            1         1          28          31
 * DAY_OF_YEAR             1         1         365         366
 * DAY_OF_WEEK             1         1           7           7
 * DAY_OF_WEEK_IN_MONTH   -1        -1           4           6
 * AM_PM                   0         0           1           1
 * HOUR                    0         0          11          11
 * HOUR_OF_DAY             0         0          23          23
 * MINUTE                  0         0          59          59
 * SECOND                  0         0          59          59
 * MILLISECOND             0         0         999         999
 * ZONE_OFFSET           -12*      -12*         12*         12*
 * DST_OFFSET              0         0           1*          1*
 * YEAR_WOY                1         1      140742      144683
 * DOW_LOCAL               1         1           7           7
 * </pre>
 * (*) In units of one-hour
 */

#if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL)
#include <stdio.h>
#endif

U_NAMESPACE_BEGIN

UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GregorianCalendar)

// 00:00:00 UTC, October 15, 1582, expressed in ms from the epoch.
// Note that only Italy and other Catholic countries actually
// observed this cutover.  Most other countries followed in
// the next few centuries, some as late as 1928. [LIU]
// in Java, -12219292800000L
//const UDate GregorianCalendar::kPapalCutover = -12219292800000L;
static const uint32_t kCutoverJulianDay = 2299161;
static const UDate kPapalCutover = (2299161.0 - kEpochStartAsJulianDay) * U_MILLIS_PER_DAY;
static const UDate kPapalCutoverJulian = (2299161.0 - kEpochStartAsJulianDay);

// -------------------------------------

GregorianCalendar::GregorianCalendar(UErrorCode& status)
    :   Calendar(TimeZone::createDefault(), Locale::getDefault(), status),
        fGregorianCutover(kPapalCutover),
	fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582),
        fIsGregorian(TRUE), fInvertGregorian(FALSE)
{
    setTimeInMillis(getNow(), status);
}

// -------------------------------------

GregorianCalendar::GregorianCalendar(TimeZone* zone, UErrorCode& status)
    :   Calendar(zone, Locale::getDefault(), status),
        fGregorianCutover(kPapalCutover),
	fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582),
        fIsGregorian(TRUE), fInvertGregorian(FALSE)
{
    setTimeInMillis(getNow(), status);
}

// -------------------------------------

GregorianCalendar::GregorianCalendar(const TimeZone& zone, UErrorCode& status)
    :   Calendar(zone, Locale::getDefault(), status),
        fGregorianCutover(kPapalCutover),
	fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582),
        fIsGregorian(TRUE), fInvertGregorian(FALSE)
{
    setTimeInMillis(getNow(), status);
}

// -------------------------------------

GregorianCalendar::GregorianCalendar(const Locale& aLocale, UErrorCode& status)
    :   Calendar(TimeZone::createDefault(), aLocale, status),
        fGregorianCutover(kPapalCutover),
	fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582),
        fIsGregorian(TRUE), fInvertGregorian(FALSE)
{
    setTimeInMillis(getNow(), status);
}

// -------------------------------------

GregorianCalendar::GregorianCalendar(TimeZone* zone, const Locale& aLocale,
                                     UErrorCode& status)
    :   Calendar(zone, aLocale, status),
        fGregorianCutover(kPapalCutover),
	fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582),
        fIsGregorian(TRUE), fInvertGregorian(FALSE)
{
    setTimeInMillis(getNow(), status);
}

// -------------------------------------

GregorianCalendar::GregorianCalendar(const TimeZone& zone, const Locale& aLocale,
                                     UErrorCode& status)
    :   Calendar(zone, aLocale, status),
        fGregorianCutover(kPapalCutover),
	fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582),
        fIsGregorian(TRUE), fInvertGregorian(FALSE)
{
    setTimeInMillis(getNow(), status);
}

// -------------------------------------

GregorianCalendar::GregorianCalendar(int32_t year, int32_t month, int32_t date,
                                     UErrorCode& status)
    :   Calendar(TimeZone::createDefault(), Locale::getDefault(), status),
        fGregorianCutover(kPapalCutover),
	fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582),
        fIsGregorian(TRUE), fInvertGregorian(FALSE)
{
    set(UCAL_ERA, AD);
    set(UCAL_YEAR, year);
    set(UCAL_MONTH, month);
    set(UCAL_DATE, date);
}

// -------------------------------------

GregorianCalendar::GregorianCalendar(int32_t year, int32_t month, int32_t date,
                                     int32_t hour, int32_t minute, UErrorCode& status)
    :   Calendar(TimeZone::createDefault(), Locale::getDefault(), status),
        fGregorianCutover(kPapalCutover),
	fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582),
        fIsGregorian(TRUE), fInvertGregorian(FALSE)
{
    set(UCAL_ERA, AD);
    set(UCAL_YEAR, year);
    set(UCAL_MONTH, month);
    set(UCAL_DATE, date);
    set(UCAL_HOUR_OF_DAY, hour);
    set(UCAL_MINUTE, minute);
}

// -------------------------------------

GregorianCalendar::GregorianCalendar(int32_t year, int32_t month, int32_t date,
                                     int32_t hour, int32_t minute, int32_t second,
                                     UErrorCode& status)
    :   Calendar(TimeZone::createDefault(), Locale::getDefault(), status),
        fGregorianCutover(kPapalCutover),
	fCutoverJulianDay(kCutoverJulianDay), fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582),
        fIsGregorian(TRUE), fInvertGregorian(FALSE)
{
    set(UCAL_ERA, AD);
    set(UCAL_YEAR, year);
    set(UCAL_MONTH, month);
    set(UCAL_DATE, date);
    set(UCAL_HOUR_OF_DAY, hour);
    set(UCAL_MINUTE, minute);
    set(UCAL_SECOND, second);
}

// -------------------------------------

GregorianCalendar::~GregorianCalendar()
{
}

// -------------------------------------

GregorianCalendar::GregorianCalendar(const GregorianCalendar &source)
    :   Calendar(source),
        fGregorianCutover(source.fGregorianCutover),
        fCutoverJulianDay(source.fCutoverJulianDay), fNormalizedGregorianCutover(source.fNormalizedGregorianCutover), fGregorianCutoverYear(source.fGregorianCutoverYear),
        fIsGregorian(source.fIsGregorian), fInvertGregorian(source.fInvertGregorian)
{
}

// -------------------------------------

Calendar* GregorianCalendar::clone() const
{
    return new GregorianCalendar(*this);
}

// -------------------------------------

GregorianCalendar &
GregorianCalendar::operator=(const GregorianCalendar &right)
{
    if (this != &right)
    {
        Calendar::operator=(right);
        fGregorianCutover = right.fGregorianCutover;
        fNormalizedGregorianCutover = right.fNormalizedGregorianCutover;
        fGregorianCutoverYear = right.fGregorianCutoverYear;
        fCutoverJulianDay = right.fCutoverJulianDay;
    }
    return *this;
}

// -------------------------------------

UBool GregorianCalendar::isEquivalentTo(const Calendar& other) const
{
    // Calendar override.
    return Calendar::isEquivalentTo(other) &&
        fGregorianCutover == ((GregorianCalendar*)&other)->fGregorianCutover;
}

// -------------------------------------

void
GregorianCalendar::setGregorianChange(UDate date, UErrorCode& status)
{
    if (U_FAILURE(status)) 
        return;

    fGregorianCutover = date;

    // Precompute two internal variables which we use to do the actual
    // cutover computations.  These are the normalized cutover, which is the
    // midnight at or before the cutover, and the cutover year.  The
    // normalized cutover is in pure date milliseconds; it contains no time
    // of day or timezone component, and it used to compare against other
    // pure date values.
    int32_t cutoverDay = (int32_t)Math::floorDivide(fGregorianCutover, (double)kOneDay);
    fNormalizedGregorianCutover = cutoverDay * kOneDay;

    // Handle the rare case of numeric overflow.  If the user specifies a
    // change of UDate(Long.MIN_VALUE), in order to get a pure Gregorian
    // calendar, then the epoch day is -106751991168, which when multiplied
    // by ONE_DAY gives 9223372036794351616 -- the negative value is too
    // large for 64 bits, and overflows into a positive value.  We correct
    // this by using the next day, which for all intents is semantically
    // equivalent.
    if (cutoverDay < 0 && fNormalizedGregorianCutover > 0) {
        fNormalizedGregorianCutover = (cutoverDay + 1) * kOneDay;
    }

    // Normalize the year so BC values are represented as 0 and negative
    // values.
    GregorianCalendar *cal = new GregorianCalendar(getTimeZone(), status);
    /* test for NULL */
    if (cal == 0) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    if(U_FAILURE(status))
        return;
    cal->setTime(date, status);
    fGregorianCutoverYear = cal->get(UCAL_YEAR, status);
    if (cal->get(UCAL_ERA, status) == BC) 
        fGregorianCutoverYear = 1 - fGregorianCutoverYear;
    fCutoverJulianDay = cutoverDay;
    delete cal;
}


void GregorianCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status) {
  int32_t eyear, month, dayOfMonth, dayOfYear;

  
  if(U_FAILURE(status)) { 
    return; 
  }

#if defined (U_DEBUG_CAL)
    fprintf(stderr, "%s:%d: jd%d- (greg's %d)- [cut=%d]\n", 
            __FILE__, __LINE__, julianDay, getGregorianDayOfYear(), fCutoverJulianDay);
#endif


  if (julianDay >= fCutoverJulianDay) {
    month = getGregorianMonth();
    dayOfMonth = getGregorianDayOfMonth();
    dayOfYear = getGregorianDayOfYear();
    eyear = getGregorianYear();
  } else {
    // The Julian epoch day (not the same as Julian Day)
    // is zero on Saturday December 30, 0 (Gregorian).
    int32_t julianEpochDay = julianDay - (kJan1_1JulianDay - 2);
    eyear = (int32_t) Math::floorDivide(4*julianEpochDay + 1464, 1461);
    
    // Compute the Julian calendar day number for January 1, eyear
    int32_t january1 = 365*(eyear-1) + Math::floorDivide(eyear-1, (int32_t)4);
    dayOfYear = (julianEpochDay - january1); // 0-based
    
    // Julian leap years occurred historically every 4 years starting
    // with 8 AD.  Before 8 AD the spacing is irregular; every 3 years
    // from 45 BC to 9 BC, and then none until 8 AD.  However, we don't
    // implement this historical detail; instead, we implement the
    // computatinally cleaner proleptic calendar, which assumes
    // consistent 4-year cycles throughout time.
    UBool isLeap = ((eyear&0x3) == 0); // equiv. to (eyear%4 == 0)
    
    // Common Julian/Gregorian calculation
    int32_t correction = 0;
    int32_t march1 = isLeap ? 60 : 59; // zero-based DOY for March 1
    if (dayOfYear >= march1) {
      correction = isLeap ? 1 : 2;
    }
    month = (12 * (dayOfYear + correction) + 6) / 367; // zero-based month
    dayOfMonth = dayOfYear - (isLeap?kLeapNumDays[month]:kNumDays[month]) + 1; // one-based DOM
    ++dayOfYear;
#if defined (U_DEBUG_CAL)
//     fprintf(stderr, "%d - %d[%d] + 1\n", dayOfYear, isLeap?kLeapNumDays[month]:kNumDays[month], month );
//           fprintf(stderr, "%s:%d:  greg's HCF %d -> %d/%d/%d not %d/%d/%d\n", 
//                   __FILE__, __LINE__,julianDay,
// 			eyear,month,dayOfMonth,
// 			getGregorianYear(), getGregorianMonth(), getGregorianDayOfMonth()  );
    fprintf(stderr, "%s:%d: doy %d (greg's %d)- [cut=%d]\n", 
            __FILE__, __LINE__, dayOfYear, getGregorianDayOfYear(), fCutoverJulianDay);
#endif

  }

  // [j81] if we are after the cutover in its year, shift the day of the year
  if((eyear == fGregorianCutoverYear) && (julianDay >= fCutoverJulianDay)) {
    //from handleComputeMonthStart
    int32_t gregShift = Grego::gregorianShift(eyear);
#if defined (U_DEBUG_CAL)
    fprintf(stderr, "%s:%d:  gregorian shift %d :::  doy%d => %d [cut=%d]\n",
            __FILE__, __LINE__,gregShift, dayOfYear, dayOfYear+gregShift, fCutoverJulianDay);
#endif
    dayOfYear += gregShift;
  }

  internalSet(UCAL_MONTH, month);
  internalSet(UCAL_DAY_OF_MONTH, dayOfMonth);
  internalSet(UCAL_DAY_OF_YEAR, dayOfYear);
  internalSet(UCAL_EXTENDED_YEAR, eyear);
  int32_t era = AD;
  if (eyear < 1) {
    era = BC;
    eyear = 1 - eyear;
  }
  internalSet(UCAL_ERA, era);
  internalSet(UCAL_YEAR, eyear);
}


// -------------------------------------

UDate
GregorianCalendar::getGregorianChange() const
{
    return fGregorianCutover;
}

// -------------------------------------

UBool 
GregorianCalendar::isLeapYear(int32_t year) const
{
    // MSVC complains bitterly if we try to use Grego::isLeapYear here
    // NOTE: year&0x3 == year%4
    return (year >= fGregorianCutoverYear ?
        (((year&0x3) == 0) && ((year%100 != 0) || (year%400 == 0))) : // Gregorian
        ((year&0x3) == 0)); // Julian
}

// -------------------------------------

int32_t GregorianCalendar::handleComputeJulianDay(UCalendarDateFields bestField) 
{
  fInvertGregorian = FALSE;

  int32_t jd = Calendar::handleComputeJulianDay(bestField);

  if((bestField == UCAL_WEEK_OF_YEAR) &&  // if we are doing WOY calculations, we are counting relative to Jan 1 *julian*
     (internalGet(UCAL_EXTENDED_YEAR)==fGregorianCutoverYear) && 
     jd >= fCutoverJulianDay) { 
    fInvertGregorian = TRUE;  // So that the Julian Jan 1 will be used in handleComputeMonthStart
    return Calendar::handleComputeJulianDay(bestField);
  }


  // The following check handles portions of the cutover year BEFORE the
  // cutover itself happens.
  //if ((fIsGregorian==TRUE) != (jd >= fCutoverJulianDay)) {  /*  cutoverJulianDay)) { */
  if ((fIsGregorian==TRUE) != (jd >= fCutoverJulianDay)) {  /*  cutoverJulianDay)) { */
#if defined (U_DEBUG_CAL)
    fprintf(stderr, "%s:%d: jd [invert] %d\n", 
            __FILE__, __LINE__, jd);
#endif
    fInvertGregorian = TRUE;
    jd = Calendar::handleComputeJulianDay(bestField);
#if defined (U_DEBUG_CAL)
    fprintf(stderr, "%s:%d:  fIsGregorian %s, fInvertGregorian %s - ", 
            __FILE__, __LINE__,fIsGregorian?"T":"F", fInvertGregorian?"T":"F");
   fprintf(stderr, " jd NOW %d\n", 
           jd);
#endif
  } else {
#if defined (U_DEBUG_CAL)
    fprintf(stderr, "%s:%d: jd [==] %d - %sfIsGregorian %sfInvertGregorian, %d\n", 
            __FILE__, __LINE__, jd, fIsGregorian?"T":"F", fInvertGregorian?"T":"F", bestField);
#endif
  }
  
  if(fIsGregorian && (internalGet(UCAL_EXTENDED_YEAR) == fGregorianCutoverYear)) {
    int32_t gregShift = Grego::gregorianShift(internalGet(UCAL_EXTENDED_YEAR));
    if (bestField == UCAL_DAY_OF_YEAR) {
#if defined (U_DEBUG_CAL)
      fprintf(stderr, "%s:%d: [DOY%d] gregorian shift of JD %d += %d\n", 
              __FILE__, __LINE__, fFields[bestField],jd, gregShift);
#endif
      jd -= gregShift;
    } else if ( bestField == UCAL_WEEK_OF_MONTH ) {
      int32_t weekShift = 14;
#if defined (U_DEBUG_CAL)
      fprintf(stderr, "%s:%d: [WOY/WOM] gregorian week shift of %d += %d\n", 
              __FILE__, __LINE__, jd, weekShift);
#endif
      jd += weekShift; // shift by weeks for week based fields.
    }
  }
  
  return jd;
}

int32_t GregorianCalendar::handleComputeMonthStart(int32_t eyear, int32_t month,

                                                   UBool /* useMonth */) const
{
    GregorianCalendar *nonConstThis = (GregorianCalendar*)this; // cast away const

    // If the month is out of range, adjust it into range, and
    // modify the extended year value accordingly.
    if (month < 0 || month > 11) {
      eyear += Math::floorDivide(month, 12, month);
    }

    UBool isLeap = eyear%4 == 0;
    int32_t y = eyear-1;
    int32_t julianDay = 365*y + Math::floorDivide(y, 4) + (kJan1_1JulianDay - 3);

    nonConstThis->fIsGregorian = (eyear >= fGregorianCutoverYear);
#if defined (U_DEBUG_CAL)
    fprintf(stderr, "%s:%d: (hcms%d/%d) fIsGregorian %s, fInvertGregorian %s\n", 
            __FILE__, __LINE__, eyear,month, fIsGregorian?"T":"F", fInvertGregorian?"T":"F");
#endif
    if (fInvertGregorian) {
        nonConstThis->fIsGregorian = !fIsGregorian;
    }
    if (fIsGregorian) {
        isLeap = isLeap && ((eyear%100 != 0) || (eyear%400 == 0));
        // Add 2 because Gregorian calendar starts 2 days after
        // Julian calendar
        int32_t gregShift = Grego::gregorianShift(eyear);
#if defined (U_DEBUG_CAL)
        fprintf(stderr, "%s:%d: (hcms%d/%d) gregorian shift of %d += %d\n", 
                __FILE__, __LINE__, eyear, month, julianDay, gregShift);
#endif
        julianDay += gregShift;
    }

    // At this point julianDay indicates the day BEFORE the first
    // day of January 1, <eyear> of either the Julian or Gregorian
    // calendar.

    if (month != 0) {
        julianDay += isLeap?kLeapNumDays[month]:kNumDays[month];
    }

    return julianDay;
}

int32_t GregorianCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month)  const
{
    return isLeapYear(extendedYear) ? kLeapMonthLength[month] : kMonthLength[month];
}

int32_t GregorianCalendar::handleGetYearLength(int32_t eyear) const {
    return isLeapYear(eyear) ? 366 : 365;
}


int32_t
GregorianCalendar::monthLength(int32_t month) const
{
    int32_t year = internalGet(UCAL_EXTENDED_YEAR);
    return handleGetMonthLength(year, month);
}

// -------------------------------------

int32_t
GregorianCalendar::monthLength(int32_t month, int32_t year) const
{
    return isLeapYear(year) ? kLeapMonthLength[month] : kMonthLength[month];
}

// -------------------------------------

int32_t
GregorianCalendar::yearLength(int32_t year) const
{
    return isLeapYear(year) ? 366 : 365;
}

// -------------------------------------

int32_t
GregorianCalendar::yearLength() const
{
    return isLeapYear(internalGet(UCAL_YEAR)) ? 366 : 365;
}

// -------------------------------------

/**
 * After adjustments such as add(MONTH), add(YEAR), we don't want the
 * month to jump around.  E.g., we don't want Jan 31 + 1 month to go to Mar
 * 3, we want it to go to Feb 28.  Adjustments which might run into this
 * problem call this method to retain the proper month.
 */
void 
GregorianCalendar::pinDayOfMonth() 
{
    int32_t monthLen = monthLength(internalGet(UCAL_MONTH));
    int32_t dom = internalGet(UCAL_DATE);
    if(dom > monthLen) 
        set(UCAL_DATE, monthLen);
}

// -------------------------------------


UBool
GregorianCalendar::validateFields() const
{
    for (int32_t field = 0; field < UCAL_FIELD_COUNT; field++) {
        // Ignore DATE and DAY_OF_YEAR which are handled below
        if (field != UCAL_DATE &&
            field != UCAL_DAY_OF_YEAR &&
            isSet((UCalendarDateFields)field) &&
            ! boundsCheck(internalGet((UCalendarDateFields)field), (UCalendarDateFields)field))
            return FALSE;
    }

    // Values differ in Least-Maximum and Maximum should be handled
    // specially.
    if (isSet(UCAL_DATE)) {
        int32_t date = internalGet(UCAL_DATE);
        if (date < getMinimum(UCAL_DATE) ||
            date > monthLength(internalGet(UCAL_MONTH))) {
            return FALSE;
        }
    }

    if (isSet(UCAL_DAY_OF_YEAR)) {
        int32_t days = internalGet(UCAL_DAY_OF_YEAR);
        if (days < 1 || days > yearLength()) {
            return FALSE;
        }
    }

    // Handle DAY_OF_WEEK_IN_MONTH, which must not have the value zero.
    // We've checked against minimum and maximum above already.
    if (isSet(UCAL_DAY_OF_WEEK_IN_MONTH) &&
        0 == internalGet(UCAL_DAY_OF_WEEK_IN_MONTH)) {
            return FALSE;
    }

    return TRUE;
}

// -------------------------------------

UBool
GregorianCalendar::boundsCheck(int32_t value, UCalendarDateFields field) const
{
    return value >= getMinimum(field) && value <= getMaximum(field);
}

// -------------------------------------

UDate 
GregorianCalendar::getEpochDay(UErrorCode& status) 
{
    complete(status);
    // Divide by 1000 (convert to seconds) in order to prevent overflow when
    // dealing with UDate(Long.MIN_VALUE) and UDate(Long.MAX_VALUE).
    double wallSec = internalGetTime()/1000 + (internalGet(UCAL_ZONE_OFFSET) + internalGet(UCAL_DST_OFFSET))/1000;
    
    return Math::floorDivide(wallSec, kOneDay/1000.0);
}

// -------------------------------------


// -------------------------------------

/**
 * Compute the julian day number of the day BEFORE the first day of
 * January 1, year 1 of the given calendar.  If julianDay == 0, it
 * specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian
 * or Gregorian).
 */
double GregorianCalendar::computeJulianDayOfYear(UBool isGregorian,
                                                 int32_t year, UBool& isLeap) {
    isLeap = year%4 == 0;
    int32_t y = year - 1;
    double julianDay = 365.0*y + Math::floorDivide(y, 4) + (kJan1_1JulianDay - 3);

    if (isGregorian) {
        isLeap = isLeap && ((year%100 != 0) || (year%400 == 0));
        // Add 2 because Gregorian calendar starts 2 days after Julian calendar
        julianDay += Grego::gregorianShift(year);
    }

    return julianDay;
}

// /**
//  * Compute the day of week, relative to the first day of week, from
//  * 0..6, of the current DOW_LOCAL or DAY_OF_WEEK fields.  This is
//  * equivalent to get(DOW_LOCAL) - 1.
//  */
// int32_t GregorianCalendar::computeRelativeDOW() const {
//     int32_t relDow = 0;
//     if (fStamp[UCAL_DOW_LOCAL] > fStamp[UCAL_DAY_OF_WEEK]) {
//         relDow = internalGet(UCAL_DOW_LOCAL) - 1; // 1-based
//     } else if (fStamp[UCAL_DAY_OF_WEEK] != kUnset) {
//         relDow = internalGet(UCAL_DAY_OF_WEEK) - getFirstDayOfWeek();
//         if (relDow < 0) relDow += 7;
//     }
//     return relDow;
// }

// /**
//  * Compute the day of week, relative to the first day of week,
//  * from 0..6 of the given julian day.
//  */
// int32_t GregorianCalendar::computeRelativeDOW(double julianDay) const {
//   int32_t relDow = julianDayToDayOfWeek(julianDay) - getFirstDayOfWeek();
//     if (relDow < 0) {
//         relDow += 7;
//     }
//     return relDow;
// }

// /**
//  * Compute the DOY using the WEEK_OF_YEAR field and the julian day
//  * of the day BEFORE January 1 of a year (a return value from
//  * computeJulianDayOfYear).
//  */
// int32_t GregorianCalendar::computeDOYfromWOY(double julianDayOfYear) const {
//     // Compute DOY from day of week plus week of year

//     // Find the day of the week for the first of this year.  This
//     // is zero-based, with 0 being the locale-specific first day of
//     // the week.  Add 1 to get first day of year.
//     int32_t fdy = computeRelativeDOW(julianDayOfYear + 1);

//     return
//         // Compute doy of first (relative) DOW of WOY 1
//         (((7 - fdy) < getMinimalDaysInFirstWeek())
//          ? (8 - fdy) : (1 - fdy))
                
//         // Adjust for the week number.
//         + (7 * (internalGet(UCAL_WEEK_OF_YEAR) - 1))

//         // Adjust for the DOW
//         + computeRelativeDOW();
// }

// -------------------------------------

double 
GregorianCalendar::millisToJulianDay(UDate millis)
{
    return (double)kEpochStartAsJulianDay + Math::floorDivide(millis, (double)kOneDay);
}

// -------------------------------------

UDate
GregorianCalendar::julianDayToMillis(double julian)
{
    return (UDate) ((julian - kEpochStartAsJulianDay) * (double) kOneDay);
}

// -------------------------------------

int32_t
GregorianCalendar::aggregateStamp(int32_t stamp_a, int32_t stamp_b) 
{
    return (((stamp_a != kUnset && stamp_b != kUnset) 
        ? uprv_max(stamp_a, stamp_b)
        : kUnset));
}

// -------------------------------------

/**
 * Roll a field by a signed amount.
 * Note: This will be made public later. [LIU]
 */
 
void 
GregorianCalendar::roll(EDateFields field, int32_t amount, UErrorCode& status) {
        roll((UCalendarDateFields) field, amount, status); 
}

void
GregorianCalendar::roll(UCalendarDateFields field, int32_t amount, UErrorCode& status)
{
  if((amount == 0) || U_FAILURE(status)) {
    return;
  }

  // J81 processing. (gregorian cutover)
  UBool inCutoverMonth = FALSE;
  int32_t cMonthLen=0; // 'c' for cutover; in days
  int32_t cDayOfMonth=0; // no discontinuity: [0, cMonthLen)
  double cMonthStart=0.0; // in ms

  // Common code - see if we're in the cutover month of the cutover year
  if(get(UCAL_EXTENDED_YEAR, status) == fGregorianCutoverYear) {
    switch (field) {
    case UCAL_DAY_OF_MONTH:
    case UCAL_WEEK_OF_MONTH:
      {
        int32_t max = monthLength(internalGet(UCAL_MONTH));
        UDate t = internalGetTime();
        // We subtract 1 from the DAY_OF_MONTH to make it zero-based, and an
        // additional 10 if we are after the cutover. Thus the monthStart
        // value will be correct iff we actually are in the cutover month.
        cDayOfMonth = internalGet(UCAL_DAY_OF_MONTH) - ((t >= fGregorianCutover) ? 10 : 0);
        cMonthStart = t - ((cDayOfMonth - 1) * kOneDay);
        // A month containing the cutover is 10 days shorter.
        if ((cMonthStart < fGregorianCutover) &&
            (cMonthStart + (cMonthLen=(max-10))*kOneDay >= fGregorianCutover)) {
          inCutoverMonth = TRUE;
        }
      }
    default:
      ;
    }
  }

  switch (field) {
  case UCAL_WEEK_OF_YEAR: {
    // Unlike WEEK_OF_MONTH, WEEK_OF_YEAR never shifts the day of the
    // week.  Also, rolling the week of the year can have seemingly
    // strange effects simply because the year of the week of year
    // may be different from the calendar year.  For example, the
    // date Dec 28, 1997 is the first day of week 1 of 1998 (if
    // weeks start on Sunday and the minimal days in first week is
    // <= 3).
    int32_t woy = get(UCAL_WEEK_OF_YEAR, status);
    // Get the ISO year, which matches the week of year.  This
    // may be one year before or after the calendar year.
    int32_t isoYear = get(UCAL_YEAR_WOY, status);
    int32_t isoDoy = internalGet(UCAL_DAY_OF_YEAR);
    if (internalGet(UCAL_MONTH) == UCAL_JANUARY) {
      if (woy >= 52) {
        isoDoy += handleGetYearLength(isoYear);
      }
    } else {
      if (woy == 1) {
        isoDoy -= handleGetYearLength(isoYear - 1);
      }
    }
    woy += amount;
    // Do fast checks to avoid unnecessary computation:
    if (woy < 1 || woy > 52) {
      // Determine the last week of the ISO year.
      // We do this using the standard formula we use
      // everywhere in this file.  If we can see that the
      // days at the end of the year are going to fall into
      // week 1 of the next year, we drop the last week by
      // subtracting 7 from the last day of the year.
      int32_t lastDoy = handleGetYearLength(isoYear);
      int32_t lastRelDow = (lastDoy - isoDoy + internalGet(UCAL_DAY_OF_WEEK) -
                            getFirstDayOfWeek()) % 7;
      if (lastRelDow < 0) lastRelDow += 7;
      if ((6 - lastRelDow) >= getMinimalDaysInFirstWeek()) lastDoy -= 7;
      int32_t lastWoy = weekNumber(lastDoy, lastRelDow + 1);
      woy = ((woy + lastWoy - 1) % lastWoy) + 1;
    }
    set(UCAL_WEEK_OF_YEAR, woy);
    set(UCAL_YEAR_WOY,isoYear);
    return;
  }

  case UCAL_DAY_OF_MONTH:
    if( !inCutoverMonth ) { 
      Calendar::roll(field, amount, status);
      return;
    } else {
      // [j81] 1582 special case for DOM
      // The default computation works except when the current month
      // contains the Gregorian cutover.  We handle this special case
      // here.  [j81 - aliu]
      double monthLen = cMonthLen * kOneDay;
      double msIntoMonth = uprv_fmod(internalGetTime() - cMonthStart +
                                     amount * kOneDay, monthLen);
      if (msIntoMonth < 0) {
        msIntoMonth += monthLen;
      }
#if defined (U_DEBUG_CAL)
      fprintf(stderr, "%s:%d: roll DOM %d  -> %.0lf ms  \n", 
              __FILE__, __LINE__,amount, cMonthLen, cMonthStart+msIntoMonth);
#endif
      setTimeInMillis(cMonthStart + msIntoMonth, status);
      return;
    }

  case UCAL_WEEK_OF_MONTH:
    if( !inCutoverMonth ) { 
      Calendar::roll(field, amount, status);
      return;
    } else {
#if defined (U_DEBUG_CAL)
      fprintf(stderr, "%s:%d: roll WOM %d ??????????????????? \n", 
              __FILE__, __LINE__,amount);
#endif
      // NOTE: following copied from  the old
      //     GregorianCalendar::roll( WEEK_OF_MONTH )  code 

      // This is tricky, because during the roll we may have to shift
      // to a different day of the week.  For example:
      
      //    s  m  t  w  r  f  s
      //          1  2  3  4  5
      //    6  7  8  9 10 11 12
      
      // When rolling from the 6th or 7th back one week, we go to the
      // 1st (assuming that the first partial week counts).  The same
      // thing happens at the end of the month.
      
      // The other tricky thing is that we have to figure out whether
      // the first partial week actually counts or not, based on the
      // minimal first days in the week.  And we have to use the
      // correct first day of the week to delineate the week
      // boundaries.
      
      // Here's our algorithm.  First, we find the real boundaries of
      // the month.  Then we discard the first partial week if it
      // doesn't count in this locale.  Then we fill in the ends with
      // phantom days, so that the first partial week and the last
      // partial week are full weeks.  We then have a nice square
      // block of weeks.  We do the usual rolling within this block,
      // as is done elsewhere in this method.  If we wind up on one of
      // the phantom days that we added, we recognize this and pin to
      // the first or the last day of the month.  Easy, eh?
      
      // Another wrinkle: To fix jitterbug 81, we have to make all this
      // work in the oddball month containing the Gregorian cutover.
      // This month is 10 days shorter than usual, and also contains
      // a discontinuity in the days; e.g., the default cutover month
      // is Oct 1582, and goes from day of month 4 to day of month 15.
      
      // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
      // in this locale.  We have dow in 0..6.
      int32_t dow = internalGet(UCAL_DAY_OF_WEEK) - getFirstDayOfWeek();
      if (dow < 0) 
        dow += 7;
      
      // Find the day of month, compensating for cutover discontinuity.
      int32_t dom = cDayOfMonth;
      
      // Find the day of the week (normalized for locale) for the first
      // of the month.
      int32_t fdm = (dow - dom + 1) % 7;
      if (fdm < 0) 
        fdm += 7;
      
      // Get the first day of the first full week of the month,
      // including phantom days, if any.  Figure out if the first week
      // counts or not; if it counts, then fill in phantom days.  If
      // not, advance to the first real full week (skip the partial week).
      int32_t start;
      if ((7 - fdm) < getMinimalDaysInFirstWeek())
        start = 8 - fdm; // Skip the first partial week
      else
        start = 1 - fdm; // This may be zero or negative
      
      // Get the day of the week (normalized for locale) for the last
      // day of the month.
      int32_t monthLen = cMonthLen;
      int32_t ldm = (monthLen - dom + dow) % 7;
      // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here.
      
      // Get the limit day for the blocked-off rectangular month; that
      // is, the day which is one past the last day of the month,
      // after the month has already been filled in with phantom days
      // to fill out the last week.  This day has a normalized DOW of 0.
      int32_t limit = monthLen + 7 - ldm;
      
      // Now roll between start and (limit - 1).
      int32_t gap = limit - start;
      int32_t newDom = (dom + amount*7 - start) % gap;
      if (newDom < 0) 
        newDom += gap;
      newDom += start;
      
      // Finally, pin to the real start and end of the month.
      if (newDom < 1) 
        newDom = 1;
      if (newDom > monthLen) 
        newDom = monthLen;
      
      // Set the DAY_OF_MONTH.  We rely on the fact that this field
      // takes precedence over everything else (since all other fields
      // are also set at this point).  If this fact changes (if the
      // disambiguation algorithm changes) then we will have to unset
      // the appropriate fields here so that DAY_OF_MONTH is attended
      // to.
      
      // If we are in the cutover month, manipulate ms directly.  Don't do
      // this in general because it doesn't work across DST boundaries
      // (details, details).  This takes care of the discontinuity.
      setTimeInMillis(cMonthStart + (newDom-1)*kOneDay, status);                
      return;
    }
    
  default:
    Calendar::roll(field, amount, status);
    return;
  }
}

// -------------------------------------


/**
 * Return the minimum value that this field could have, given the current date.
 * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
 * @param field    the time field.
 * @return         the minimum value that this field could have, given the current date.
 * @deprecated ICU 2.6. Use getActualMinimum(UCalendarDateFields field) instead.
 */
int32_t GregorianCalendar::getActualMinimum(EDateFields field) const
{
    return getMinimum((UCalendarDateFields)field);
}

int32_t GregorianCalendar::getActualMinimum(EDateFields field, UErrorCode& /* status */) const
{
    return getMinimum((UCalendarDateFields)field);
}

/**
 * Return the minimum value that this field could have, given the current date.
 * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
 * @param field    the time field.
 * @return         the minimum value that this field could have, given the current date.
 * @draft ICU 2.6.
 */
int32_t GregorianCalendar::getActualMinimum(UCalendarDateFields field, UErrorCode& /* status */) const
{
    return getMinimum(field);
}


// ------------------------------------

/**
  * Old year limits were least max 292269054, max 292278994.
  */

/**
 * @stable ICU 2.0
 */
int32_t GregorianCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const {
    return kGregorianCalendarLimits[field][limitType];
}

/**
 * Return the maximum value that this field could have, given the current date.
 * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual
 * maximum would be 28; for "Feb 3, 1996" it s 29.  Similarly for a Hebrew calendar,
 * for some years the actual maximum for MONTH is 12, and for others 13.
 * @stable ICU 2.0
 */
int32_t GregorianCalendar::getActualMaximum(UCalendarDateFields field, UErrorCode& status) const
{
    /* It is a known limitation that the code here (and in getActualMinimum)
        * won't behave properly at the extreme limits of GregorianCalendar's
        * representable range (except for the code that handles the YEAR
        * field).  That's because the ends of the representable range are at
        * odd spots in the year.  For calendars with the default Gregorian
        * cutover, these limits are Sun Dec 02 16:47:04 GMT 292269055 BC to Sun
        * Aug 17 07:12:55 GMT 292278994 AD, somewhat different for non-GMT
        * zones.  As a result, if the calendar is set to Aug 1 292278994 AD,
        * the actual maximum of DAY_OF_MONTH is 17, not 30.  If the date is Mar
        * 31 in that year, the actual maximum month might be Jul, whereas is
        * the date is Mar 15, the actual maximum might be Aug -- depending on
        * the precise semantics that are desired.  Similar considerations
        * affect all fields.  Nonetheless, this effect is sufficiently arcane
        * that we permit it, rather than complicating the code to handle such
        * intricacies. - liu 8/20/98

        * UPDATE: No longer true, since we have pulled in the limit values on
        * the year. - Liu 11/6/00 */

    switch (field) {

    case UCAL_YEAR:
        /* The year computation is no different, in principle, from the
            * others, however, the range of possible maxima is large.  In
            * addition, the way we know we've exceeded the range is different.
            * For these reasons, we use the special case code below to handle
            * this field.
            *
            * The actual maxima for YEAR depend on the type of calendar:
            *
            *     Gregorian = May 17, 292275056 BC - Aug 17, 292278994 AD
            *     Julian    = Dec  2, 292269055 BC - Jan  3, 292272993 AD
            *     Hybrid    = Dec  2, 292269055 BC - Aug 17, 292278994 AD
            *
            * We know we've exceeded the maximum when either the month, date,
            * time, or era changes in response to setting the year.  We don't
            * check for month, date, and time here because the year and era are
            * sufficient to detect an invalid year setting.  NOTE: If code is
            * added to check the month and date in the future for some reason,
            * Feb 29 must be allowed to shift to Mar 1 when setting the year.
            */
        {
            if(U_FAILURE(status)) return 0;
            Calendar *cal = clone();
            if(!cal) {
                status = U_MEMORY_ALLOCATION_ERROR;
                return 0;
            }
            
            cal->setLenient(TRUE);
            
            int32_t era = cal->get(UCAL_ERA, status);
            UDate d = cal->getTime(status);

            /* Perform a binary search, with the invariant that lowGood is a
                * valid year, and highBad is an out of range year.
                */
            int32_t lowGood = kGregorianCalendarLimits[UCAL_YEAR][1];
            int32_t highBad = kGregorianCalendarLimits[UCAL_YEAR][2]+1;
            while ((lowGood + 1) < highBad) {
                int32_t y = (lowGood + highBad) / 2;
                cal->set(UCAL_YEAR, y);
                if (cal->get(UCAL_YEAR, status) == y && cal->get(UCAL_ERA, status) == era) {
                    lowGood = y;
                } else {
                    highBad = y;
                    cal->setTime(d, status); // Restore original fields
                }
            }
            
            delete cal;
            return lowGood;
        }

    default:
        return Calendar::getActualMaximum(field,status);
    }
}


int32_t GregorianCalendar::handleGetExtendedYear() {
  int32_t year = kEpochYear;
  switch(resolveFields(kYearPrecedence)) {
  case UCAL_EXTENDED_YEAR:
    year = internalGet(UCAL_EXTENDED_YEAR, kEpochYear);
    break;
  
  case UCAL_YEAR:
    {
      // The year defaults to the epoch start, the era to AD
      int32_t era = internalGet(UCAL_ERA, AD);
      if (era == BC) {
        year = 1 - internalGet(UCAL_YEAR, 1); // Convert to extended year
      } else {
        year = internalGet(UCAL_YEAR, kEpochYear);
      }
    }
    break;

  case UCAL_YEAR_WOY:
    year = handleGetExtendedYearFromWeekFields(internalGet(UCAL_YEAR_WOY), internalGet(UCAL_WEEK_OF_YEAR));
#if defined (U_DEBUG_CAL)
    //    if(internalGet(UCAL_YEAR_WOY) != year) {
    fprintf(stderr, "%s:%d: hGEYFWF[%d,%d] ->  %d\n", 
    __FILE__, __LINE__,internalGet(UCAL_YEAR_WOY),internalGet(UCAL_WEEK_OF_YEAR),year);
      //}
#endif
    break;

    default:	
        year = kEpochYear;	
  }
  return year;
}

int32_t GregorianCalendar::handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t woy)
{
  // convert year to extended form
  int32_t era = internalGet(UCAL_ERA, AD);
  if(era == BC) {
    yearWoy = 1 - yearWoy;
  }
  return Calendar::handleGetExtendedYearFromWeekFields(yearWoy, woy);
}


// -------------------------------------

UBool
GregorianCalendar::inDaylightTime(UErrorCode& status) const
{
    if (U_FAILURE(status) || !getTimeZone().useDaylightTime()) 
        return FALSE;

    // Force an update of the state of the Calendar.
    ((GregorianCalendar*)this)->complete(status); // cast away const

    return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE);
}

// -------------------------------------

/**
 * Return the ERA.  We need a special method for this because the
 * default ERA is AD, but a zero (unset) ERA is BC.
 */
int32_t
GregorianCalendar::internalGetEra() const {
    return isSet(UCAL_ERA) ? internalGet(UCAL_ERA) : AD;
}

const char *
GregorianCalendar::getType() const {
  //static const char kGregorianType = "gregorian";

  return "gregorian";
}

const UDate     GregorianCalendar::fgSystemDefaultCentury        = DBL_MIN;
const int32_t   GregorianCalendar::fgSystemDefaultCenturyYear    = -1;

UDate           GregorianCalendar::fgSystemDefaultCenturyStart       = DBL_MIN;
int32_t         GregorianCalendar::fgSystemDefaultCenturyStartYear   = -1;


UBool GregorianCalendar::haveDefaultCentury() const
{
  return TRUE;
}

UDate GregorianCalendar::defaultCenturyStart() const
{
  return internalGetDefaultCenturyStart();
}

int32_t GregorianCalendar::defaultCenturyStartYear() const
{
  return internalGetDefaultCenturyStartYear();
}

UDate
GregorianCalendar::internalGetDefaultCenturyStart() const
{
  // lazy-evaluate systemDefaultCenturyStart
  UBool needsUpdate;
  { 
    Mutex m;
    needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
  }

  if (needsUpdate) {
    initializeSystemDefaultCentury();
  }

  // use defaultCenturyStart unless it's the flag value;
  // then use systemDefaultCenturyStart
  
  return fgSystemDefaultCenturyStart;
}

int32_t
GregorianCalendar::internalGetDefaultCenturyStartYear() const
{
  // lazy-evaluate systemDefaultCenturyStartYear
  UBool needsUpdate;
  { 
    Mutex m;
    needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
  }

  if (needsUpdate) {
    initializeSystemDefaultCentury();
  }

  // use defaultCenturyStart unless it's the flag value;
  // then use systemDefaultCenturyStartYear
  
  return    fgSystemDefaultCenturyStartYear;
}

void
GregorianCalendar::initializeSystemDefaultCentury()
{
  // initialize systemDefaultCentury and systemDefaultCenturyYear based
  // on the current time.  They'll be set to 80 years before
  // the current time.
  // No point in locking as it should be idempotent.
  if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury)
  {
    UErrorCode status = U_ZERO_ERROR;
    Calendar *calendar = new GregorianCalendar(status);
    if (calendar != NULL && U_SUCCESS(status))
    {
      calendar->setTime(Calendar::getNow(), status);
      calendar->add(UCAL_YEAR, -80, status);

      UDate    newStart =  calendar->getTime(status);
      int32_t  newYear  =  calendar->get(UCAL_YEAR, status);
      {
        Mutex m;
        fgSystemDefaultCenturyStart = newStart;
        fgSystemDefaultCenturyStartYear = newYear;
      }
      delete calendar;
    }
    // We have no recourse upon failure unless we want to propagate the failure
    // out.
  }
}


U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

//eof
