/*
*******************************************************************************
* Copyright (C) 1997-2006, 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

// setTimeInMillis() limits the Julian day range to +/-7F000000.
// This would seem to limit the year range to:
//  ms=+183882168921600000  jd=7f000000  December 20, 5828963 AD
//  ms=-184303902528000000  jd=81000000  September 20, 5838270 BC
// HOWEVER, CalendarRegressionTest/Test4167060 shows that the actual
// range limit on the year field is smaller (~ +/-140000). [alan 3.0]

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)
        : (int32_t)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) : (int32_t)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
