/*
*******************************************************************************
* Copyright (C) 1997-2004, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
* File CALENDAR.CPP
*
* Modification History:
*
*   Date        Name        Description
*   02/03/97    clhuang     Creation.
*   04/22/97    aliu        Cleaned up, fixed memory leak, made 
*                           setWeekCountData() more robust.  
*                           Moved platform code to TPlatformUtilities.
*   05/01/97    aliu        Made equals(), before(), after() arguments const.
*   05/20/97    aliu        Changed logic of when to compute fields and time
*                           to fix bugs.
*   08/12/97    aliu        Added equivalentTo.  Misc other fixes.
*   07/28/98    stephen     Sync up with JDK 1.2
*   09/02/98    stephen     Sync with JDK 1.2 8/31 build (getActualMin/Max)
*   03/17/99    stephen     Changed adoptTimeZone() - now fAreFieldsSet is
*                           set to FALSE to force update of time.
*******************************************************************************
*/

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/resbund.h"
#include "unicode/gregocal.h"
#include "gregoimp.h"
#include "buddhcal.h"
#include "japancal.h"
#include "islamcal.h"
#include "hebrwcal.h"
#include "chnsecal.h"
#include "unicode/calendar.h"
#include "cpputils.h"
#include "iculserv.h"
#include "ucln_in.h"
#include "cstring.h"
#include "locbased.h"

U_NAMESPACE_BEGIN

// ------------------------------------------
//
// Registration
//
//-------------------------------------------
//#define U_DEBUG_CALSVC 1
//

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


/**
 * convert a UCalendarDateFields into a string - for debugging
 * @param f field enum
 * @return static string to the field name
 * @internal
 */
static const char* fldName(UCalendarDateFields f) {
    switch (f) {
#define FIELD_NAME_STR(x) case x: return (#x+5)
      FIELD_NAME_STR( UCAL_ERA );
      FIELD_NAME_STR( UCAL_YEAR );
      FIELD_NAME_STR( UCAL_MONTH );
      FIELD_NAME_STR( UCAL_WEEK_OF_YEAR );
      FIELD_NAME_STR( UCAL_WEEK_OF_MONTH );
      FIELD_NAME_STR( UCAL_DATE );
      FIELD_NAME_STR( UCAL_DAY_OF_YEAR );
      FIELD_NAME_STR( UCAL_DAY_OF_WEEK );
      FIELD_NAME_STR( UCAL_DAY_OF_WEEK_IN_MONTH );
      FIELD_NAME_STR( UCAL_AM_PM );
      FIELD_NAME_STR( UCAL_HOUR );
      FIELD_NAME_STR( UCAL_HOUR_OF_DAY );
      FIELD_NAME_STR( UCAL_MINUTE );
      FIELD_NAME_STR( UCAL_SECOND );
      FIELD_NAME_STR( UCAL_MILLISECOND );
      FIELD_NAME_STR( UCAL_ZONE_OFFSET );
      FIELD_NAME_STR( UCAL_DST_OFFSET );
      FIELD_NAME_STR( UCAL_YEAR_WOY );
      FIELD_NAME_STR( UCAL_DOW_LOCAL );
      FIELD_NAME_STR( UCAL_EXTENDED_YEAR );
      FIELD_NAME_STR( UCAL_JULIAN_DAY );
      FIELD_NAME_STR( UCAL_MILLISECONDS_IN_DAY );
#undef FIELD_NAME_STR
    default:
      return "??";
    }
}

#endif


static ICULocaleService* gService = NULL;

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

static const char *gBasicCalendars[] = { "@calendar=gregorian", "@calendar=japanese",
                                         "@calendar=buddhist", "@calendar=islamic-civil",
                                         "@calendar=islamic", "@calendar=hebrew", "@calendar=chinese",
                                         NULL };

/**
 * a Calendar Factory which creates the "basic" calendar types, that is, those 
 * shipped with ICU.
 */
class BasicCalendarFactory : public LocaleKeyFactory {
public:
  /**
   * @param calendarType static const string (caller owns storage - will be aliased) to calendar type
   */
  BasicCalendarFactory()
    : LocaleKeyFactory(LocaleKeyFactory::INVISIBLE) { }
  
  virtual ~BasicCalendarFactory() {}

protected:
  virtual UBool isSupportedID( const UnicodeString& id, UErrorCode& status) const { 
    if(U_FAILURE(status)) {
      return FALSE;
    }
    for(int32_t i=0;gBasicCalendars[i] != NULL;i++) {
      UnicodeString ourId(gBasicCalendars[i],"");
      if(ourId == id) {
        return TRUE;
      }
    }
    return FALSE;
  }

  virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const
  {
    if (U_SUCCESS(status)) {
      for(int32_t i=0;gBasicCalendars[i] != NULL;i++) {
        UnicodeString id(gBasicCalendars[i],"");
        result.put(id, (void*)this, status);
      }
    }
  }

  virtual UObject* create(const ICUServiceKey& key, const ICUService* /*service*/, UErrorCode& status) const {
#ifdef U_DEBUG_CALSVC
    if(key.getDynamicClassID() != LocaleKey::getStaticClassID()) {
      fprintf(stderr, "::create - not a LocaleKey!\n");
    }
#endif
    const LocaleKey& lkey = (LocaleKey&)key;
    Locale curLoc;  // current locale
    Locale canLoc;  // Canonical locale

    lkey.currentLocale(curLoc);
    lkey.canonicalLocale(canLoc);

    UnicodeString str;
    key.currentID(str);

    char tmp[200];
      // Extract a char* out of it..
      int32_t len = str.length();
      int32_t actLen = sizeof(tmp)-1;
      if(len > actLen) {
        len = actLen;
      }
      str.extract(0,len,tmp);
      tmp[len]=0;


#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "BasicCalendarFactory::create() - cur %s, can %s\n", (const char*)curLoc.getName(), (const char*)canLoc.getName());
#endif

    if(!isSupportedID(str,status)) {  // Do we handle this type?
#ifdef U_DEBUG_CALSVC
      
      fprintf(stderr, "BasicCalendarFactory - not handling %s.[%s]\n", (const char*) curLoc.getName(), tmp );
#endif
      return NULL;
    }

#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "BasicCalendarFactory %p: creating type for %s\n", 
            this, (const char*)curLoc.getName());
    fflush(stderr);
#endif

  if(!tmp || !*tmp || !uprv_strcmp(tmp,"@calendar=gregorian")) {  // Gregorian (default)
    return new GregorianCalendar(canLoc, status);
  } else if(!uprv_strcmp(tmp, "@calendar=japanese")) {
    return new JapaneseCalendar(canLoc, status);
  } else if(!uprv_strcmp(tmp, "@calendar=buddhist")) {
    return new BuddhistCalendar(canLoc, status);
  } else if(!uprv_strcmp(tmp, "@calendar=islamic-civil")) {
    return new IslamicCalendar(canLoc, status, IslamicCalendar::CIVIL);
  } else if(!uprv_strcmp(tmp, "@calendar=islamic")) {
    return new IslamicCalendar(canLoc, status, IslamicCalendar::ASTRONOMICAL);
  } else if(!uprv_strcmp(tmp, "@calendar=hebrew")) {
    return new HebrewCalendar(canLoc, status);
  //} else if(!uprv_strcmp(tmp, "@calendar=chinese")) {
  //return new ChineseCalendar(canLoc, status);
  } else { 
    status = U_UNSUPPORTED_ERROR;
    return NULL;
  }
 }
};


/** 
 * A factory which looks up the DefaultCalendar resource to determine which class of calendar to use
 */

class DefaultCalendarFactory : public ICUResourceBundleFactory {
 public:
  DefaultCalendarFactory():  ICUResourceBundleFactory() { } 
 protected:
  virtual UObject* create(const ICUServiceKey& key, const ICUService* /*service*/, UErrorCode& status) const  {
    
    LocaleKey &lkey = (LocaleKey&)key;
    Locale loc;
    lkey.currentLocale(loc);
    
    UnicodeString myString;
    
    // attempt keyword lookup
    char keyword[128];

    if(!loc.getKeywordValue("calendar", keyword, sizeof(keyword)-1, status)) {
      // fetch default calendar id
      const char *defaultCal = NULL;
      char funcEquiv[256];
      ures_getFunctionalEquivalent(funcEquiv, sizeof(funcEquiv)-1,
                                   NULL, "calendar", "calendar",
                                   loc.getName(), 
                                   NULL, FALSE, &status);
      uloc_getKeywordValue(funcEquiv, "calendar", keyword, 
                           sizeof(keyword)-1, &status);
#ifdef U_DEBUG_CALSVC
      fprintf(stderr, "  getFunctionalEquivalent calendar=%s [%s]\n", keyword, u_errorName(status));
#endif
    }
#ifdef U_DEBUG_CALSVC
    else { fprintf(stderr, "  explicit calendar=%s\n", keyword); }
#endif


    if(U_FAILURE(status)) {
      return NULL; 
    } else {
      UnicodeString *ret = new UnicodeString("@calendar=","");
      (*ret) += UnicodeString(keyword, "");
      return ret;
    }
  }
};

// -------------------------------------
class CalendarService : public ICULocaleService {
public:
  CalendarService()
    : ICULocaleService("Calendar")
  {
    UErrorCode status = U_ZERO_ERROR;
    registerFactory(new DefaultCalendarFactory(), status);
  }

  virtual UObject* cloneInstance(UObject* instance) const {
    if(instance->getDynamicClassID() == UnicodeString::getStaticClassID()) {
      return ((UnicodeString*)instance)->clone(); 
    } else {
#ifdef U_DEBUG_CALSVC_F
      UErrorCode status2 = U_ZERO_ERROR;
      fprintf(stderr, "Cloning a %s calendar with tz=%ld\n", ((Calendar*)instance)->getType(), ((Calendar*)instance)->get(UCAL_ZONE_OFFSET, status2));
#endif
      return ((Calendar*)instance)->clone();
    }
  }

  virtual UObject* handleDefault(const ICUServiceKey& key, UnicodeString* /*actualID*/, UErrorCode& status) const {
	LocaleKey& lkey = (LocaleKey&)key;
	//int32_t kind = lkey.kind();

	Locale loc;
	lkey.canonicalLocale(loc);

#ifdef U_DEBUG_CALSVC
        Locale loc2;
        lkey.currentLocale(loc2);
    fprintf(stderr, "CalSvc:handleDefault for currentLoc %s, canloc %s\n", (const char*)loc.getName(),  (const char*)loc2.getName());
#endif
	Calendar *nc =  new GregorianCalendar(loc, status);

#ifdef U_DEBUG_CALSVC
        UErrorCode status2 = U_ZERO_ERROR;
        fprintf(stderr, "New default calendar has tz=%d\n", ((Calendar*)nc)->get(UCAL_ZONE_OFFSET, status2));
#endif
        return nc;
  }

  virtual UBool isDefault() const {
    return countFactories() == 1;
  }
};

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

static ICULocaleService* 
getCalendarService(void)
{
  UBool needInit;
  {
    Mutex mutex;
    needInit = (UBool)(gService == NULL);
  }
  if (needInit) {
    UErrorCode status = U_ZERO_ERROR;
#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "Spinning up Calendar Service\n");
#endif
    ICULocaleService * newservice = new CalendarService();
#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "Registering classes..\n");
#endif

    // Register all basic instances. 
    newservice->registerFactory(new BasicCalendarFactory(),status);

#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "Done..\n");
#endif

    if(U_FAILURE(status)) {
#ifdef U_DEBUG_CALSVC
      fprintf(stderr, "err (%s) registering classes, deleting service.....\n", u_errorName(status));
#endif
      delete newservice;
      newservice = NULL;
    }
    
    if (newservice) {
      Mutex mutex;
      if (gService == NULL) {
        gService = newservice;
        newservice = NULL;
      }
    }
    if (newservice) {
      delete newservice;
    } else {
      // we won the contention - we can register the cleanup.
      ucln_i18n_registerCleanup();
    }
  }
  return gService;
}

URegistryKey Calendar::registerFactory(ICUServiceFactory* toAdopt, UErrorCode& status)
{
  return getCalendarService()->registerFactory(toAdopt, status);
}

UBool Calendar::unregister(URegistryKey key, UErrorCode& status) {
  return getCalendarService()->unregister(key, status);
}

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

static const int32_t kCalendarLimits[UCAL_FIELD_COUNT][4] = {
    //    Minimum  Greatest min      Least max   Greatest max
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // ERA
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // YEAR
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // MONTH
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // WEEK_OF_YEAR
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // WEEK_OF_MONTH
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // DAY_OF_MONTH
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // DAY_OF_YEAR
    {           1,            1,             7,             7  }, // DAY_OF_WEEK
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // DAY_OF_WEEK_IN_MONTH
    {           0,            0,             1,             1  }, // AM_PM
    {           0,            0,            11,            11  }, // HOUR
    {           0,            0,            23,            23  }, // HOUR_OF_DAY
    {           0,            0,            59,            59  }, // MINUTE
    {           0,            0,            59,            59  }, // SECOND
    {           0,            0,           999,           999  }, // MILLISECOND
    {-12*kOneHour, -12*kOneHour,   12*kOneHour,   15*kOneHour  }, // ZONE_OFFSET
    {           0,            0,    1*kOneHour,    1*kOneHour  }, // DST_OFFSET
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // YEAR_WOY
    {           1,            1,             7,             7  }, // DOW_LOCAL
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // EXTENDED_YEAR
    { -0x7F000000,  -0x7F000000,    0x7F000000,    0x7F000000  }, // JULIAN_DAY
    {           0,            0, 24*kOneHour-1, 24*kOneHour-1  } // MILLISECONDS_IN_DAY
};

// Resource bundle tags read by this class
const char Calendar::kDateTimeElements[] = "DateTimeElements";

// Data flow in Calendar
// ---------------------

// The current time is represented in two ways by Calendar: as UTC
// milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local
// fields such as MONTH, HOUR, AM_PM, etc.  It is possible to compute the
// millis from the fields, and vice versa.  The data needed to do this
// conversion is encapsulated by a TimeZone object owned by the Calendar.
// The data provided by the TimeZone object may also be overridden if the
// user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
// keeps track of what information was most recently set by the caller, and
// uses that to compute any other information as needed.

// If the user sets the fields using set(), the data flow is as follows.
// This is implemented by the Calendar subclass's computeTime() method.
// During this process, certain fields may be ignored.  The disambiguation
// algorithm for resolving which fields to pay attention to is described
// above.

//   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
//           |
//           | Using Calendar-specific algorithm
//           V
//   local standard millis
//           |
//           | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
//           V
//   UTC millis (in time data member)

// If the user sets the UTC millis using setTime(), the data flow is as
// follows.  This is implemented by the Calendar subclass's computeFields()
// method.

//   UTC millis (in time data member)
//           |
//           | Using TimeZone getOffset()
//           V
//   local standard millis
//           |
//           | Using Calendar-specific algorithm
//           V
//   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)

// In general, a round trip from fields, through local and UTC millis, and
// back out to fields is made when necessary.  This is implemented by the
// complete() method.  Resolving a partial set of fields into a UTC millis
// value allows all remaining fields to be generated from that value.  If
// the Calendar is lenient, the fields are also renormalized to standard
// ranges when they are regenerated.

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

Calendar::Calendar(UErrorCode& success)
:   UObject(),
    fIsTimeSet(FALSE),
    fAreFieldsSet(FALSE),
    fAreAllFieldsSet(FALSE),
    fAreFieldsVirtuallySet(FALSE),
    fNextStamp((int32_t)kMinimumUserStamp),
    fTime(0),
    fLenient(TRUE),
    fZone(0)
{
    clear();
    fZone = TimeZone::createDefault();
    setWeekCountData(Locale::getDefault(), NULL, success);
}

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

Calendar::Calendar(TimeZone* zone, const Locale& aLocale, UErrorCode& success)
:   UObject(),
    fIsTimeSet(FALSE),
    fAreFieldsSet(FALSE),
    fAreAllFieldsSet(FALSE),
    fAreFieldsVirtuallySet(FALSE),
    fNextStamp((int32_t)kMinimumUserStamp),
    fTime(0),
    fLenient(TRUE),
    fZone(0)
{
    if(zone == 0) {
#if defined (U_DEBUG_CAL)
      fprintf(stderr, "%s:%d: ILLEGAL ARG because timezone cannot be 0\n",
              __FILE__, __LINE__);
#endif
      success = U_ILLEGAL_ARGUMENT_ERROR;
      return;
    }

    clear();    
    fZone = zone;
    
    setWeekCountData(aLocale, NULL, success);
}

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

Calendar::Calendar(const TimeZone& zone, const Locale& aLocale, UErrorCode& success)
:   UObject(),
    fIsTimeSet(FALSE),
    fAreFieldsSet(FALSE),
    fAreAllFieldsSet(FALSE),
    fAreFieldsVirtuallySet(FALSE),
    fNextStamp((int32_t)kMinimumUserStamp),
    fTime(0),
    fLenient(TRUE),
    fZone(0)
{
    clear();
    fZone = zone.clone();
    setWeekCountData(aLocale, NULL, success);
}

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

Calendar::~Calendar()
{
    delete fZone;
}

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

Calendar::Calendar(const Calendar &source)
:   UObject(source)
{
    fZone = 0;
    *this = source;
}

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

Calendar &
Calendar::operator=(const Calendar &right)
{
    if (this != &right) {
        uprv_arrayCopy(right.fFields, fFields, UCAL_FIELD_COUNT);
        uprv_arrayCopy(right.fIsSet, fIsSet, UCAL_FIELD_COUNT);
        uprv_arrayCopy(right.fStamp, fStamp, UCAL_FIELD_COUNT);
        fTime                    = right.fTime;
        fIsTimeSet               = right.fIsTimeSet;
        fAreAllFieldsSet         = right.fAreAllFieldsSet;
        fAreFieldsSet            = right.fAreFieldsSet;
        fAreFieldsVirtuallySet   = right.fAreFieldsVirtuallySet;
        fLenient                 = right.fLenient;
        delete fZone;
        fZone                    = right.fZone->clone();
        fFirstDayOfWeek          = right.fFirstDayOfWeek;
        fMinimalDaysInFirstWeek  = right.fMinimalDaysInFirstWeek;
        fNextStamp               = right.fNextStamp;
    }
    
    return *this;
}

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

Calendar*
Calendar::createInstance(UErrorCode& success)
{
  return createInstance(TimeZone::createDefault(), Locale::getDefault(), success);
}

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

Calendar*
Calendar::createInstance(const TimeZone& zone, UErrorCode& success)
{
  return createInstance(zone, Locale::getDefault(), success);
}

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

Calendar*
Calendar::createInstance(const Locale& aLocale, UErrorCode& success)
{
  return createInstance(TimeZone::createDefault(), aLocale, success);
}

// ------------------------------------- Adopting 

// Note: this is the bottleneck that actually calls the service routines.

Calendar*
Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& success)
{
  Locale actualLoc;
  UObject* u = getCalendarService()->get(aLocale, LocaleKey::KIND_ANY, &actualLoc, success);
  Calendar* c = NULL;

  if(U_FAILURE(success) || !u) {
    delete zone;
    if(U_SUCCESS(success)) { // Propagate some kind of err
      success = U_INTERNAL_PROGRAM_ERROR;
    }
    return NULL;
  }

  if(u->getDynamicClassID() == UnicodeString::getStaticClassID()) {
    // It's a unicode string telling us what type of calendar to load ("gregorian", etc)
    char tmp[200];
    const UnicodeString& str = *(UnicodeString*)u;
    // Extract a char* out of it..
    int32_t len = str.length();
    int32_t actLen = sizeof(tmp)-1;
    if(len > actLen) {
      len = actLen;
    }
    str.extract(0,len,tmp);
    tmp[len]=0;
    
#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "Calendar::createInstance(%s), fetched string %s..\n", (const char*)aLocale.getName(), tmp);
#endif

    // Create a Locale over this string
    Locale l = Locale::createFromName(tmp);

#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "looking up [%s].. should be %s\n",l.getName(), tmp);
#endif

    Locale actualLoc2;
    delete u;
    u = NULL;

    // Don't overwrite actualLoc, since the actual loc from this call
    // may be something like "@calendar=gregorian" -- TODO investigate
    // further...
    c = (Calendar*)getCalendarService()->get(l, LocaleKey::KIND_ANY, &actualLoc2, success);

    if(U_FAILURE(success) || !c) {
      delete zone;
      if(U_SUCCESS(success)) { 
        success = U_INTERNAL_PROGRAM_ERROR; // Propagate some err
      }
      return NULL;
    }
    
    if(c->getDynamicClassID() == UnicodeString::getStaticClassID()) {
      // recursed! Second lookup returned a UnicodeString. 
      // Perhaps DefaultCalendar{} was set to another locale.
#ifdef U_DEBUG_CALSVC
      char tmp[200];
      const UnicodeString& str = *(UnicodeString*)c;
      // Extract a char* out of it..
      int32_t len = str.length();
      int32_t actLen = sizeof(tmp)-1;
      if(len > actLen) {
        len = actLen;
      }
      str.extract(0,len,tmp);
      tmp[len]=0;

      fprintf(stderr, "err - recursed, 2nd lookup was unistring %s\n", tmp);
#endif
      success = U_MISSING_RESOURCE_ERROR;  // requested a calendar type which could NOT be found.
      delete c;
      delete zone;
      return NULL;
    }
#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "%p: setting week count data to locale %s, actual locale %s\n", c, (const char*)aLocale.getName(), (const char *)actualLoc.getName());
#endif
    c->setWeekCountData(aLocale, c->getType(), success);  // set the correct locale (this was an indirected calendar)
  } else {
    // a calendar was returned - we assume the factory did the right thing.
    c = (Calendar*)u;
  }

  // Now, reset calendar to default state:
  c->adoptTimeZone(zone); //  Set the correct time zone
  c->setTimeInMillis(getNow(), success); // let the new calendar have the current time.
  
  return c;
}

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

Calendar*
Calendar::createInstance(const TimeZone& zone, const Locale& aLocale, UErrorCode& success)
{
  Calendar* c = createInstance(aLocale, success);
  if(U_SUCCESS(success) && c) {
    c->setTimeZone(zone);
  }
  return c; 
}

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

UBool
Calendar::operator==(const Calendar& that) const
{
    UErrorCode status = U_ZERO_ERROR;
    return isEquivalentTo(that) &&
        getTimeInMillis(status) == that.getTimeInMillis(status) &&
        U_SUCCESS(status);
}

UBool 
Calendar::isEquivalentTo(const Calendar& other) const
{
    return getDynamicClassID() == other.getDynamicClassID() &&
        fLenient                == other.fLenient &&
        fFirstDayOfWeek         == other.fFirstDayOfWeek &&
        fMinimalDaysInFirstWeek == other.fMinimalDaysInFirstWeek &&
        *fZone                  == *other.fZone;
}

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

UBool
Calendar::equals(const Calendar& when, UErrorCode& status) const
{
    return (this == &when ||
            getTime(status) == when.getTime(status));
}

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

UBool
Calendar::before(const Calendar& when, UErrorCode& status) const
{
    return (this != &when &&
            getTimeInMillis(status) < when.getTimeInMillis(status));
}

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

UBool
Calendar::after(const Calendar& when, UErrorCode& status) const
{
    return (this != &when &&
            getTimeInMillis(status) > when.getTimeInMillis(status));
}

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


const Locale*
Calendar::getAvailableLocales(int32_t& count)
{
    return Locale::getAvailableLocales(count);
}

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

UDate
Calendar::getNow()
{
    return (UDate)uprv_getUTCtime() * U_MILLIS_PER_SECOND; // return as milliseconds
}

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

/**
 * Gets this Calendar's current time as a long.
 * @return the current time as UTC milliseconds from the epoch.
 */
double 
Calendar::getTimeInMillis(UErrorCode& status) const
{
    if(U_FAILURE(status)) 
        return 0.0;

    if ( ! fIsTimeSet) 
        ((Calendar*)this)->updateTime(status);

    /* Test for buffer overflows */
    if(U_FAILURE(status)) {
        return 0.0;
    }
    return fTime;
}

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

/**
 * Sets this Calendar's current time from the given long value.
 * @param date the new time in UTC milliseconds from the epoch.
 */
void 
Calendar::setTimeInMillis( double millis, UErrorCode& status ) {
    if(U_FAILURE(status)) 
        return;

    if (millis > MAX_MILLIS) {
        millis = MAX_MILLIS;
    } else if (millis < MIN_MILLIS) {
        millis = MIN_MILLIS;
    }

    fTime = millis;
    fAreFieldsSet = fAreAllFieldsSet = FALSE;
    fIsTimeSet = fAreFieldsVirtuallySet = TRUE;
}

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

int32_t
Calendar::get(UCalendarDateFields field, UErrorCode& status) const
{
    // field values are only computed when actually requested; for more on when computation
    // of various things happens, see the "data flow in Calendar" description at the top
    // of this file
    if (U_SUCCESS(status)) ((Calendar*)this)->complete(status); // Cast away const
    return U_SUCCESS(status) ? fFields[field] : 0;
}

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

void
Calendar::set(UCalendarDateFields field, int32_t value)
{
    if (fAreFieldsVirtuallySet) {
        UErrorCode ec = U_ZERO_ERROR;
        computeFields(ec);
    }
    fFields[field]     = value;
    fStamp[field]     = fNextStamp++;
    fIsSet[field]     = TRUE; // Remove later
    fIsTimeSet = fAreFieldsSet = fAreFieldsVirtuallySet = FALSE;
}

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

void
Calendar::set(int32_t year, int32_t month, int32_t date)
{
    set(UCAL_YEAR, year);
    set(UCAL_MONTH, month);
    set(UCAL_DATE, date);
}

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

void
Calendar::set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute)
{
    set(UCAL_YEAR, year);
    set(UCAL_MONTH, month);
    set(UCAL_DATE, date);
    set(UCAL_HOUR_OF_DAY, hour);
    set(UCAL_MINUTE, minute);
}

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

void
Calendar::set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute, int32_t second)
{
    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);
}

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

void
Calendar::clear()
{
    for (int32_t i=0; i<UCAL_FIELD_COUNT; ++i) {
        fFields[i]     = 0; // Must do this; other code depends on it
        fStamp[i]     = kUnset;
        fIsSet[i]     = FALSE; // Remove later
    }
    fIsTimeSet = fAreFieldsSet = fAreAllFieldsSet = fAreFieldsVirtuallySet = FALSE;
}

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

void
Calendar::clear(UCalendarDateFields field)
{
    if (fAreFieldsVirtuallySet) {
        UErrorCode ec = U_ZERO_ERROR;
        computeFields(ec);
    }
    fFields[field]         = 0;
    fStamp[field]         = kUnset;
    fIsSet[field]         = FALSE; // Remove later
    fIsTimeSet = fAreFieldsSet = fAreAllFieldsSet = fAreFieldsVirtuallySet = FALSE;
}

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

UBool
Calendar::isSet(UCalendarDateFields field) const
{
    return fAreFieldsVirtuallySet || (fStamp[field] != kUnset);
}


int32_t Calendar::newestStamp(UCalendarDateFields first, UCalendarDateFields last, int32_t bestStampSoFar) const
{
  int32_t bestStamp = bestStampSoFar;
  for (int32_t i=(int32_t)first; i<=(int32_t)last; ++i) {
    if (fStamp[i] > bestStamp) {
      bestStamp = fStamp[i];
    }
  }
  return bestStamp;
}


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

void
Calendar::complete(UErrorCode& status)
{
    if (!fIsTimeSet) {
        updateTime(status);
        /* Test for buffer overflows */
        if(U_FAILURE(status)) {
            return;
        }
    }
    if (!fAreFieldsSet) {
        computeFields(status); // fills in unset fields
        /* Test for buffer overflows */
        if(U_FAILURE(status)) {
            return;
        }
        fAreFieldsSet         = TRUE;
        fAreAllFieldsSet     = TRUE;
    }
}

    //-------------------------------------------------------------------------
    // Protected utility methods for use by subclasses.  These are very handy
    // for implementing add, roll, and computeFields.
    //-------------------------------------------------------------------------

    /**
     * Adjust the specified field so that it is within
     * the allowable range for the date to which this calendar is set.
     * For example, in a Gregorian calendar pinning the {@link #DAY_OF_MONTH DAY_OF_MONTH}
     * field for a calendar set to April 31 would cause it to be set
     * to April 30.
     * <p>
     * <b>Subclassing:</b>
     * <br>
     * This utility method is intended for use by subclasses that need to implement
     * their own overrides of {@link #roll roll} and {@link #add add}.
     * <p>
     * <b>Note:</b>
     * <code>pinField</code> is implemented in terms of
     * {@link #getActualMinimum getActualMinimum}
     * and {@link #getActualMaximum getActualMaximum}.  If either of those methods uses
     * a slow, iterative algorithm for a particular field, it would be
     * unwise to attempt to call <code>pinField</code> for that field.  If you
     * really do need to do so, you should override this method to do
     * something more efficient for that field.
     * <p>
     * @param field The calendar field whose value should be pinned.
     *
     * @see #getActualMinimum
     * @see #getActualMaximum
     * @stable ICU 2.0
     */
void Calendar::pinField(UCalendarDateFields field, UErrorCode& status) {
  int32_t max = getActualMaximum(field, status);
  int32_t min = getActualMinimum(field, status);
  
  if (fFields[field] > max) {
    set(field, max);
  } else if (fFields[field] < min) {
    set(field, min);
  }
}


void Calendar::computeFields(UErrorCode &ec)
{
  if (U_FAILURE(ec)) {
    return;
  }
  // Compute local wall millis
  double localMillis = internalGetTime();
  int32_t rawOffset, dstOffset;
  getTimeZone().getOffset(localMillis, FALSE, rawOffset, dstOffset, ec);
  localMillis += rawOffset; 
  
  // Mark fields as set.  Do this before calling handleComputeFields().
  uint32_t mask =   //fInternalSetMask;
    (1 << ERA) |
    (1 << UCAL_YEAR) |
    (1 << UCAL_MONTH) |
    (1 << UCAL_DAY_OF_MONTH) | // = UCAL_DATE
    (1 << UCAL_DAY_OF_YEAR) |
    (1 << UCAL_EXTENDED_YEAR);  

  for (int32_t i=0; i<UCAL_FIELD_COUNT; ++i) {
    if ((mask & 1) == 0) {
      fStamp[i] = kInternallySet;
      fIsSet[i] = TRUE; // Remove later
    } else {
      fStamp[i] = kUnset;
      fIsSet[i] = FALSE; // Remove later
    }
    mask >>= 1;
  }
  
  // We used to check for and correct extreme millis values (near
  // Long.MIN_VALUE or Long.MAX_VALUE) here.  Such values would cause
  // overflows from positive to negative (or vice versa) and had to
  // be manually tweaked.  We no longer need to do this because we
  // have limited the range of supported dates to those that have a
  // Julian day that fits into an int.  This allows us to implement a
  // JULIAN_DAY field and also removes some inelegant code. - Liu
  // 11/6/00
  
  int32_t days =  (int32_t)Math::floorDivide(localMillis, (double)kOneDay);

  internalSet(UCAL_JULIAN_DAY,days + kEpochStartAsJulianDay);

#if defined (U_DEBUG_CAL)
  //fprintf(stderr, "%s:%d- Hmm! Jules @ %d, as per %.0lf millis\n",
  //__FILE__, __LINE__, fFields[UCAL_JULIAN_DAY], localMillis);
#endif  

  // In some cases we will have to call this method again below to
  // adjust for DST pushing us into the next Julian day.
  computeGregorianAndDOWFields(fFields[UCAL_JULIAN_DAY], ec);
  
  int32_t millisInDay =  (int32_t) (localMillis - (days * kOneDay));
  if (millisInDay < 0) millisInDay += (int32_t)kOneDay;
    
  // Adjust our millisInDay for DST.  dstOffset will be zero if DST
  // is not in effect at this time of year, or if our zone does not
  // use DST.
  millisInDay += dstOffset;
  
  // If DST has pushed us into the next day, we must call
  // computeGregorianAndDOWFields() again.  This happens in DST between
  // 12:00 am and 1:00 am every day.  The first call to
  // computeGregorianAndDOWFields() will give the wrong day, since the
  // Standard time is in the previous day.
  if (millisInDay >= (int32_t)kOneDay) {
    millisInDay -= (int32_t)kOneDay; // ASSUME dstOffset < 24:00
    
    // We don't worry about overflow of JULIAN_DAY because the
    // allowable range of JULIAN_DAY has slop at the ends (that is,
    // the max is less that 0x7FFFFFFF and the min is greater than
    // -0x80000000).
    computeGregorianAndDOWFields(++fFields[UCAL_JULIAN_DAY], ec);
  }
  
  // Call framework method to have subclass compute its fields.
  // These must include, at a minimum, MONTH, DAY_OF_MONTH,
  // EXTENDED_YEAR, YEAR, DAY_OF_YEAR.  This method will call internalSet(),
  // which will update stamp[].
  handleComputeFields(fFields[UCAL_JULIAN_DAY], ec);
  
  // Compute week-related fields, based on the subclass-computed
  // fields computed by handleComputeFields().
  computeWeekFields(ec);
  
  // Compute time-related fields.  These are indepent of the date and
  // of the subclass algorithm.  They depend only on the local zone
  // wall milliseconds in day.
  fFields[UCAL_MILLISECONDS_IN_DAY] = millisInDay;
  fFields[UCAL_MILLISECOND] = millisInDay % 1000;
  millisInDay /= 1000;
  fFields[UCAL_SECOND] = millisInDay % 60;
  millisInDay /= 60;
  fFields[UCAL_MINUTE] = millisInDay % 60;
  millisInDay /= 60;
  fFields[UCAL_HOUR_OF_DAY] = millisInDay;
  fFields[UCAL_AM_PM] = millisInDay / 12; // Assume AM == 0
  fFields[UCAL_HOUR] = millisInDay % 12;
  fFields[UCAL_ZONE_OFFSET] = rawOffset;
  fFields[UCAL_DST_OFFSET] = dstOffset;
}


/**
 * Compute the Gregorian calendar year, month, and day of month from
 * the given Julian day.  These values are not stored in fields, but in
 * member variables gregorianXxx.  Also compute the DAY_OF_WEEK and
 * DOW_LOCAL fields.
 */
void Calendar::computeGregorianAndDOWFields(int32_t julianDay, UErrorCode &ec)
{
  computeGregorianFields(julianDay, ec);
  
  // Compute day of week: JD 0 = Monday
  int32_t dow = julianDayToDayOfWeek(julianDay);
  internalSet(UCAL_DAY_OF_WEEK,dow);

  // Calculate 1-based localized day of week
  int32_t dowLocal = dow - getFirstDayOfWeek() + 1;
  if (dowLocal < 1) {
    dowLocal += 7;
  }
  internalSet(UCAL_DOW_LOCAL,dowLocal);
  fFields[UCAL_DOW_LOCAL] = dowLocal;
}

/**
 * Compute the Gregorian calendar year, month, and day of month from the
 * Julian day.  These values are not stored in fields, but in member
 * variables gregorianXxx.  They are used for time zone computations and by
 * subclasses that are Gregorian derivatives.  Subclasses may call this
 * method to perform a Gregorian calendar millis->fields computation.
 * To perform a Gregorian calendar fields->millis computation, call
 * computeGregorianMonthStart().
 * @see #computeGregorianMonthStart
 */
void Calendar::computeGregorianFields(int32_t julianDay, UErrorCode & /* ec */) {
  int32_t gregorianDayOfWeekUnused;
  Grego::dayToFields(julianDay - kEpochStartAsJulianDay, fGregorianYear, fGregorianMonth, fGregorianDayOfMonth, gregorianDayOfWeekUnused, fGregorianDayOfYear);
}

/**
 * Compute the fields WEEK_OF_YEAR, YEAR_WOY, WEEK_OF_MONTH,
 * DAY_OF_WEEK_IN_MONTH, and DOW_LOCAL from EXTENDED_YEAR, YEAR,
 * DAY_OF_WEEK, and DAY_OF_YEAR.  The latter fields are computed by the
 * subclass based on the calendar system.
 *
 * <p>The YEAR_WOY field is computed simplistically.  It is equal to YEAR
 * most of the time, but at the year boundary it may be adjusted to YEAR-1
 * or YEAR+1 to reflect the overlap of a week into an adjacent year.  In
 * this case, a simple increment or decrement is performed on YEAR, even
 * though this may yield an invalid YEAR value.  For instance, if the YEAR
 * is part of a calendar system with an N-year cycle field CYCLE, then
 * incrementing the YEAR may involve incrementing CYCLE and setting YEAR
 * back to 0 or 1.  This is not handled by this code, and in fact cannot be
 * simply handled without having subclasses define an entire parallel set of
 * fields for fields larger than or equal to a year.  This additional
 * complexity is not warranted, since the intention of the YEAR_WOY field is
 * to support ISO 8601 notation, so it will typically be used with a
 * proleptic Gregorian calendar, which has no field larger than a year.
 */
void Calendar::computeWeekFields(UErrorCode &ec) {
  if(U_FAILURE(ec)) { 
    return;
  }
  int32_t eyear = fFields[UCAL_EXTENDED_YEAR];
  int32_t year = fFields[UCAL_YEAR];
  int32_t dayOfWeek = fFields[UCAL_DAY_OF_WEEK];
  int32_t dayOfYear = fFields[UCAL_DAY_OF_YEAR];
  
  // WEEK_OF_YEAR start
  // Compute the week of the year.  For the Gregorian calendar, valid week
  // numbers run from 1 to 52 or 53, depending on the year, the first day
  // of the week, and the minimal days in the first week.  For other
  // calendars, the valid range may be different -- it depends on the year
  // length.  Days at the start of the year may fall into the last week of
  // the previous year; days at the end of the year may fall into the
  // first week of the next year.  ASSUME that the year length is less than
  // 7000 days.
  int32_t yearOfWeekOfYear = year;
  int32_t relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6
  int32_t relDowJan1 = (dayOfWeek - dayOfYear + 7001 - getFirstDayOfWeek()) % 7; // 0..6
  int32_t woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53
  if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) {
    ++woy;
  }
  
  // Adjust for weeks at the year end that overlap into the previous or
  // next calendar year.
  if (woy == 0) {
    // We are the last week of the previous year.
    // Check to see if we are in the last week; if so, we need
    // to handle the case in which we are the first week of the
    // next year.
    
    int32_t prevDoy = dayOfYear + handleGetYearLength(eyear - 1);
    woy = weekNumber(prevDoy, dayOfWeek);
    yearOfWeekOfYear--;
  } else {
    int32_t lastDoy = handleGetYearLength(eyear);
    // Fast check: For it to be week 1 of the next year, the DOY
    // must be on or after L-5, where L is yearLength(), then it
    // cannot possibly be week 1 of the next year:
    //          L-5                  L
    // doy: 359 360 361 362 363 364 365 001
    // dow:      1   2   3   4   5   6   7
    if (dayOfYear >= (lastDoy - 5)) {
      int32_t lastRelDow = (relDow + lastDoy - dayOfYear) % 7;
      if (lastRelDow < 0) {
        lastRelDow += 7;
      }
      if (((6 - lastRelDow) >= getMinimalDaysInFirstWeek()) &&
          ((dayOfYear + 7 - relDow) > lastDoy)) {
        woy = 1;
        yearOfWeekOfYear++;
      }
    }
  }
  fFields[UCAL_WEEK_OF_YEAR] = woy;
  fFields[UCAL_YEAR_WOY] = yearOfWeekOfYear;
  // WEEK_OF_YEAR end
  
  int32_t dayOfMonth = fFields[UCAL_DAY_OF_MONTH];
  fFields[UCAL_WEEK_OF_MONTH] = weekNumber(dayOfMonth, dayOfWeek);
  fFields[UCAL_DAY_OF_WEEK_IN_MONTH] = (dayOfMonth-1) / 7 + 1;
#if defined (U_DEBUG_CAL)
  if(fFields[UCAL_DAY_OF_WEEK_IN_MONTH]==0) fprintf(stderr, "%s:%d: DOWIM %d on %g\n", 
                  __FILE__, __LINE__,fFields[UCAL_DAY_OF_WEEK_IN_MONTH], fTime);
#endif
}


int32_t Calendar::weekNumber(int32_t desiredDay, int32_t dayOfPeriod, int32_t dayOfWeek)
{
  // Determine the day of the week of the first day of the period
  // in question (either a year or a month).  Zero represents the
  // first day of the week on this calendar.
  int32_t periodStartDayOfWeek = (dayOfWeek - getFirstDayOfWeek() - dayOfPeriod + 1) % 7;
  if (periodStartDayOfWeek < 0) periodStartDayOfWeek += 7;
  
  // Compute the week number.  Initially, ignore the first week, which
  // may be fractional (or may not be).  We add periodStartDayOfWeek in
  // order to fill out the first week, if it is fractional.
  int32_t weekNo = (desiredDay + periodStartDayOfWeek - 1)/7;
  
  // If the first week is long enough, then count it.  If
  // the minimal days in the first week is one, or if the period start
  // is zero, we always increment weekNo.
  if ((7 - periodStartDayOfWeek) >= getMinimalDaysInFirstWeek()) ++weekNo;
  
  return weekNo;
}

void Calendar::handleComputeFields(int32_t /* julianDay */, UErrorCode &/* status */)
{
  internalSet(UCAL_MONTH, getGregorianMonth());
  internalSet(UCAL_DAY_OF_MONTH, getGregorianDayOfMonth());
  internalSet(UCAL_DAY_OF_YEAR, getGregorianDayOfYear());
  int32_t eyear = getGregorianYear();
  internalSet(UCAL_EXTENDED_YEAR, eyear);
  int32_t era = GregorianCalendar::AD;
  if (eyear < 1) {
    era = GregorianCalendar::BC;
    eyear = 1 - eyear;
  }
  internalSet(UCAL_ERA, era);
  internalSet(UCAL_YEAR, eyear);
}
// -------------------------------------


void Calendar::roll(EDateFields field, int32_t amount, UErrorCode& status) 
{
  roll((UCalendarDateFields)field, amount, status);
}

void Calendar::roll(UCalendarDateFields field, int32_t amount, UErrorCode& status)
{
  if (amount == 0) {
    return; // Nothing to do
  }

  complete(status);

  if(U_FAILURE(status)) {
    return;
  }
  switch (field) {
  case UCAL_DAY_OF_MONTH:
  case UCAL_AM_PM:
  case UCAL_MINUTE:
  case UCAL_SECOND:
  case UCAL_MILLISECOND:
  case UCAL_MILLISECONDS_IN_DAY:
  case UCAL_ERA:
    // These are the standard roll instructions.  These work for all
    // simple cases, that is, cases in which the limits are fixed, such
    // as the hour, the day of the month, and the era.
    {
      int32_t min = getActualMinimum(field,status);
      int32_t max = getActualMaximum(field,status);
      int32_t gap = max - min + 1;

      int32_t value = internalGet(field) + amount;
      value = (value - min) % gap;
      if (value < 0) {
        value += gap;
      }
      value += min;

      set(field, value);
      return;
    }

  case UCAL_HOUR:
  case UCAL_HOUR_OF_DAY:
    // Rolling the hour is difficult on the ONSET and CEASE days of
    // daylight savings.  For example, if the change occurs at
    // 2 AM, we have the following progression:
    // ONSET: 12 Std -> 1 Std -> 3 Dst -> 4 Dst
    // CEASE: 12 Dst -> 1 Dst -> 1 Std -> 2 Std
    // To get around this problem we don't use fields; we manipulate
    // the time in millis directly.
    {
      // Assume min == 0 in calculations below
      double start = getTimeInMillis(status);
      int32_t oldHour = internalGet(field);
      int32_t max = getMaximum(field);
      int32_t newHour = (oldHour + amount) % (max + 1);
      if (newHour < 0) {
        newHour += max + 1;
      }
      setTimeInMillis(start + kOneHour * (newHour - oldHour),status);
      return;
    }

  case UCAL_MONTH:
    // Rolling the month involves both pinning the final value
    // and adjusting the DAY_OF_MONTH if necessary.  We only adjust the
    // DAY_OF_MONTH if, after updating the MONTH field, it is illegal.
    // E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>.
    {
      int32_t max = getActualMaximum(UCAL_MONTH, status);
      int32_t mon = (internalGet(UCAL_MONTH) + amount) % (max+1);

      if (mon < 0) {
        mon += (max + 1);
      }
      set(UCAL_MONTH, mon);

      // Keep the day of month in range.  We don't want to spill over
      // into the next month; e.g., we don't want jan31 + 1 mo -> feb31 ->
      // mar3.
      pinField(UCAL_DAY_OF_MONTH,status);
      return;
    }

  case UCAL_YEAR:
  case UCAL_YEAR_WOY:
  case UCAL_EXTENDED_YEAR:
    // Rolling the year can involve pinning the DAY_OF_MONTH.
    set(field, internalGet(field) + amount);
    pinField(UCAL_MONTH,status);
    pinField(UCAL_DAY_OF_MONTH,status);
    return;

  case UCAL_WEEK_OF_MONTH:
    {
      // 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?

      // 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 the week (normalized for locale) for the first
      // of the month.
      int32_t fdm = (dow - internalGet(UCAL_DAY_OF_MONTH) + 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 = getActualMaximum(UCAL_DAY_OF_MONTH, status);
      int32_t ldm = (monthLen - internalGet(UCAL_DAY_OF_MONTH) + 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 day_of_month = (internalGet(UCAL_DAY_OF_MONTH) + amount*7 -
                          start) % gap;
      if (day_of_month < 0) day_of_month += gap;
      day_of_month += start;

      // Finally, pin to the real start and end of the month.
      if (day_of_month < 1) day_of_month = 1;
      if (day_of_month > monthLen) day_of_month = 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.
      set(UCAL_DAY_OF_MONTH, day_of_month);
      return;
    }
  case UCAL_WEEK_OF_YEAR:
    {
      // This follows the outline of WEEK_OF_MONTH, except it applies
      // to the whole year.  Please see the comment for WEEK_OF_MONTH
      // for general notes.

      // 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 the week (normalized for locale) for the first
      // of the year.
      int32_t fdy = (dow - internalGet(UCAL_DAY_OF_YEAR) + 1) % 7;
      if (fdy < 0) fdy += 7;

      // Get the first day of the first full week of the year,
      // 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 - fdy) < getMinimalDaysInFirstWeek())
        start = 8 - fdy; // Skip the first partial week
      else
        start = 1 - fdy; // This may be zero or negative

      // Get the day of the week (normalized for locale) for the last
      // day of the year.
      int32_t yearLen = getActualMaximum(UCAL_DAY_OF_YEAR,status);
      int32_t ldy = (yearLen - internalGet(UCAL_DAY_OF_YEAR) + dow) % 7;
      // We know yearLen >= DAY_OF_YEAR so we skip the += 7 step here.

      // Get the limit day for the blocked-off rectangular year; that
      // is, the day which is one past the last day of the year,
      // after the year 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 = yearLen + 7 - ldy;

      // Now roll between start and (limit - 1).
      int32_t gap = limit - start;
      int32_t day_of_year = (internalGet(UCAL_DAY_OF_YEAR) + amount*7 -
                         start) % gap;
      if (day_of_year < 0) day_of_year += gap;
      day_of_year += start;

      // Finally, pin to the real start and end of the month.
      if (day_of_year < 1) day_of_year = 1;
      if (day_of_year > yearLen) day_of_year = yearLen;

      // Make sure that the year and day of year are attended to by
      // clearing other fields which would normally take precedence.
      // If the disambiguation algorithm is changed, this section will
      // have to be updated as well.
      set(UCAL_DAY_OF_YEAR, day_of_year);
      clear(UCAL_MONTH);
      return;
    }
  case UCAL_DAY_OF_YEAR:
    {
      // Roll the day of year using millis.  Compute the millis for
      // the start of the year, and get the length of the year.
      double delta = amount * kOneDay; // Scale up from days to millis
      double min2 = internalGet(UCAL_DAY_OF_YEAR)-1;
      min2 *= kOneDay;
      min2 = internalGetTime() - min2;

      //      double min2 = internalGetTime() - (internalGet(UCAL_DAY_OF_YEAR) - 1.0) * kOneDay;
      double newtime;

      double yearLength = getActualMaximum(UCAL_DAY_OF_YEAR,status);
      double oneYear = yearLength;
      oneYear *= kOneDay;
      newtime = uprv_fmod((internalGetTime() + delta - min2), oneYear);
      if (newtime < 0) newtime += oneYear;
      setTimeInMillis(newtime + min2, status);
      return;
    }
  case UCAL_DAY_OF_WEEK:
  case UCAL_DOW_LOCAL:
    {
      // Roll the day of week using millis.  Compute the millis for
      // the start of the week, using the first day of week setting.
      // Restrict the millis to [start, start+7days).
      double delta = amount * kOneDay; // Scale up from days to millis
      // Compute the number of days before the current day in this
      // week.  This will be a value 0..6.
      int32_t leadDays = internalGet(field);
      leadDays -= (field == UCAL_DAY_OF_WEEK) ? getFirstDayOfWeek() : 1;
      if (leadDays < 0) leadDays += 7;
      double min2 = internalGetTime() - leadDays * kOneDay;
      double newtime = uprv_fmod((internalGetTime() + delta - min2), kOneWeek);
      if (newtime < 0) newtime += kOneWeek;
      setTimeInMillis(newtime + min2, status);
      return;
    }
  case UCAL_DAY_OF_WEEK_IN_MONTH:
    {
      // Roll the day of week in the month using millis.  Determine
      // the first day of the week in the month, and then the last,
      // and then roll within that range.
      double delta = amount * kOneWeek; // Scale up from weeks to millis
      // Find the number of same days of the week before this one
      // in this month.
      int32_t preWeeks = (internalGet(UCAL_DAY_OF_MONTH) - 1) / 7;
      // Find the number of same days of the week after this one
      // in this month.
      int32_t postWeeks = (getActualMaximum(UCAL_DAY_OF_MONTH,status) -
                       internalGet(UCAL_DAY_OF_MONTH)) / 7;
      // From these compute the min and gap millis for rolling.
      double min2 = internalGetTime() - preWeeks * kOneWeek;
      double gap2 = kOneWeek * (preWeeks + postWeeks + 1); // Must add 1!
      // Roll within this range
      double newtime = uprv_fmod((internalGetTime() + delta - min2), gap2);
      if (newtime < 0) newtime += gap2;
      setTimeInMillis(newtime + min2, status);
      return;
    }
  case UCAL_JULIAN_DAY:
    set(field, internalGet(field) + amount);
    return;
  default:
    // Other fields cannot be rolled by this method
#if defined (U_DEBUG_CAL)
          fprintf(stderr, "%s:%d: ILLEGAL ARG because of roll on non-rollable field %s\n", 
                  __FILE__, __LINE__,fldName(field));
#endif
    status = U_ILLEGAL_ARGUMENT_ERROR;
  }
}

void Calendar::add(EDateFields field, int32_t amount, UErrorCode& status)
{
  Calendar::add((UCalendarDateFields)field, amount, status);
}

// -------------------------------------
void Calendar::add(UCalendarDateFields field, int32_t amount, UErrorCode& status)
{
  if (amount == 0) {
    return;   // Do nothing!
  }

  // We handle most fields in the same way.  The algorithm is to add
  // a computed amount of millis to the current millis.  The only
  // wrinkle is with DST -- for some fields, like the DAY_OF_MONTH,
  // we don't want the HOUR to shift due to changes in DST.  If the
  // result of the add operation is to move from DST to Standard, or
  // vice versa, we need to adjust by an hour forward or back,
  // respectively.  For such fields we set keepHourInvariant to TRUE.

  // We only adjust the DST for fields larger than an hour.  For
  // fields smaller than an hour, we cannot adjust for DST without
  // causing problems.  for instance, if you add one hour to April 5,
  // 1998, 1:00 AM, in PST, the time becomes "2:00 AM PDT" (an
  // illegal value), but then the adjustment sees the change and
  // compensates by subtracting an hour.  As a result the time
  // doesn't advance at all.

  // For some fields larger than a day, such as a UCAL_MONTH, we pin the
  // UCAL_DAY_OF_MONTH.  This allows <March 31>.add(UCAL_MONTH, 1) to be
  // <April 30>, rather than <April 31> => <May 1>.

  double delta = amount; // delta in ms
  UBool keepHourInvariant = TRUE;

  switch (field) {
  case UCAL_ERA:
    set(field, get(field, status) + amount);
    pinField(UCAL_ERA, status);
    return;

  case UCAL_YEAR:
  case UCAL_EXTENDED_YEAR:
  case UCAL_YEAR_WOY:
  case UCAL_MONTH:
    set(field, get(field, status) + amount);
    pinField(UCAL_DAY_OF_MONTH, status);
    return;

  case UCAL_WEEK_OF_YEAR:
  case UCAL_WEEK_OF_MONTH:
  case UCAL_DAY_OF_WEEK_IN_MONTH:
    delta *= kOneWeek;
    break;

  case UCAL_AM_PM:
    delta *= 12 * kOneHour;
    break;

  case UCAL_DAY_OF_MONTH:
  case UCAL_DAY_OF_YEAR:
  case UCAL_DAY_OF_WEEK:
  case UCAL_DOW_LOCAL:
  case UCAL_JULIAN_DAY:
    delta *= kOneDay;
    break;

  case UCAL_HOUR_OF_DAY:
  case UCAL_HOUR:
    delta *= kOneHour;
    keepHourInvariant = FALSE;
    break;

  case UCAL_MINUTE:
    delta *= kOneMinute;
    keepHourInvariant = FALSE;
    break;

  case UCAL_SECOND:
    delta *= kOneSecond;
    keepHourInvariant = FALSE;
    break;

  case UCAL_MILLISECOND:
  case UCAL_MILLISECONDS_IN_DAY:
    keepHourInvariant = FALSE;
    break;

  default:
#if defined (U_DEBUG_CAL)
    fprintf(stderr, "%s:%d: ILLEGAL ARG because field %s not addable",
            __FILE__, __LINE__, fldName(field));
#endif
    status = U_ILLEGAL_ARGUMENT_ERROR;
    return;
  //  throw new IllegalArgumentException("Calendar.add(" + fieldName(field) +
  //                                     ") not supported");
  }

  // In order to keep the hour invariant (for fields where this is
  // appropriate), record the DST_OFFSET before and after the add()
  // operation.  If it has changed, then adjust the millis to
  // compensate.
  int32_t dst = 0;
  int32_t hour = 0;
  if (keepHourInvariant) {
    dst = get(UCAL_DST_OFFSET, status);
    hour = internalGet(UCAL_HOUR_OF_DAY);
  }

  setTimeInMillis(getTimeInMillis(status) + delta, status);

  if (keepHourInvariant) {
    dst -= get(UCAL_DST_OFFSET, status);
    if (dst != 0) {
      // We have done an hour-invariant adjustment but the
      // DST offset has altered.  We adjust millis to keep
      // the hour constant.  In cases such as midnight after
      // a DST change which occurs at midnight, there is the
      // danger of adjusting into a different day.  To avoid
      // this we make the adjustment only if it actually
      // maintains the hour.
      double t = internalGetTime();
      setTimeInMillis(t + dst, status);
      if (get(UCAL_HOUR_OF_DAY, status) != hour) {
        setTimeInMillis(t, status);
      }
    }
  } 
}

// -------------------------------------
int32_t Calendar::fieldDifference(UDate when, EDateFields field, UErrorCode& status) {
  return fieldDifference(when, (UCalendarDateFields) field, status);
}

int32_t Calendar::fieldDifference(UDate targetMs, UCalendarDateFields field, UErrorCode& ec) {
    if (U_FAILURE(ec)) return 0;
    int32_t min = 0;
    double startMs = getTimeInMillis(ec);
    // Always add from the start millis.  This accomodates
    // operations like adding years from February 29, 2000 up to
    // February 29, 2004.  If 1, 1, 1, 1 is added to the year
    // field, the DOM gets pinned to 28 and stays there, giving an
    // incorrect DOM difference of 1.  We have to add 1, reset, 2,
    // reset, 3, reset, 4.
    if (startMs < targetMs) {
        int32_t max = 1;
        // Find a value that is too large
        while (U_SUCCESS(ec)) {
            setTimeInMillis(startMs, ec);
            add(field, max, ec);
            double ms = getTimeInMillis(ec);
            if (ms == targetMs) {
                return max;
            } else if (ms > targetMs) {
                break;
            } else {
                max <<= 1;
                if (max < 0) {
                    // Field difference too large to fit into int32_t
#if defined (U_DEBUG_CAL)
                  fprintf(stderr, "%s:%d: ILLEGAL ARG because field %s's max too large for int32_t\n",
                          __FILE__, __LINE__, fldName(field));
#endif
                    ec = U_ILLEGAL_ARGUMENT_ERROR;
                }
            }
        }
        // Do a binary search
        while ((max - min) > 1 && U_SUCCESS(ec)) {
            int32_t t = (min + max) / 2;
            setTimeInMillis(startMs, ec);
            add(field, t, ec);
            double ms = getTimeInMillis(ec);
            if (ms == targetMs) {
                return t;
            } else if (ms > targetMs) {
                max = t;
            } else {
                min = t;
            }
        }
    } else if (startMs > targetMs) {
        int32_t max = -1;
        // Find a value that is too small
        while (U_SUCCESS(ec)) {
            setTimeInMillis(startMs, ec);
            add(field, max, ec);
            double ms = getTimeInMillis(ec);
            if (ms == targetMs) {
                return max;
            } else if (ms < targetMs) {
                break;
            } else {
                max <<= 1;
                if (max == 0) {
                    // Field difference too large to fit into int32_t
#if defined (U_DEBUG_CAL)
                  fprintf(stderr, "%s:%d: ILLEGAL ARG because field %s's max too large for int32_t\n",
                          __FILE__, __LINE__, fldName(field));
#endif
                    ec = U_ILLEGAL_ARGUMENT_ERROR;
                }
            }
        }
        // Do a binary search
        while ((min - max) > 1 && U_SUCCESS(ec)) {
            int32_t t = (min + max) / 2;
            setTimeInMillis(startMs, ec);
            add(field, t, ec);
            double ms = getTimeInMillis(ec);
            if (ms == targetMs) {
                return t;
            } else if (ms < targetMs) {
                max = t;
            } else {
                min = t;
            }
        }
    }
    // Set calendar to end point
    setTimeInMillis(startMs, ec);
    add(field, min, ec);
    
    /* Test for buffer overflows */
    if(U_FAILURE(ec)) {
        return 0;
    }
    return min;
}

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

void
Calendar::adoptTimeZone(TimeZone* zone)
{
    // Do nothing if passed-in zone is NULL
    if (zone == NULL) return;

    // fZone should always be non-null
    if (fZone != NULL) delete fZone;
    fZone = zone;

    // if the zone changes, we need to recompute the time fields
    fAreFieldsSet = FALSE;
}

// -------------------------------------
void
Calendar::setTimeZone(const TimeZone& zone)
{
    adoptTimeZone(zone.clone());
}

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

const TimeZone&
Calendar::getTimeZone() const
{
    return *fZone;
}

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

TimeZone*
Calendar::orphanTimeZone()
{
    TimeZone *z = fZone;
    // we let go of the time zone; the new time zone is the system default time zone
    fZone = TimeZone::createDefault();
    return z;
}

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

void
Calendar::setLenient(UBool lenient)
{
    fLenient = lenient;
}

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

UBool
Calendar::isLenient() const
{
    return fLenient;
}

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

void
Calendar::setFirstDayOfWeek(UCalendarDaysOfWeek value)
{
  if (fFirstDayOfWeek != value &&
        value >= UCAL_SUNDAY && value <= UCAL_SATURDAY) {
        fFirstDayOfWeek = value;
        fAreFieldsSet = FALSE;
    }
}

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

Calendar::EDaysOfWeek
Calendar::getFirstDayOfWeek() const
{
    return (Calendar::EDaysOfWeek)fFirstDayOfWeek;
}

UCalendarDaysOfWeek
Calendar::getFirstDayOfWeek(UErrorCode & /*status*/) const
{
    return fFirstDayOfWeek;
}
// -------------------------------------

void
Calendar::setMinimalDaysInFirstWeek(uint8_t value)
{
    // Values less than 1 have the same effect as 1; values greater
    // than 7 have the same effect as 7. However, we normalize values
    // so operator== and so forth work.
    if (value < 1) {
        value = 1;
    } else if (value > 7) {
        value = 7;
    }
    if (fMinimalDaysInFirstWeek != value) {
        fMinimalDaysInFirstWeek = value;
        fAreFieldsSet = FALSE;
    }
}

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

uint8_t
Calendar::getMinimalDaysInFirstWeek() const
{
    return fMinimalDaysInFirstWeek;
}

// ------------------------------------- limits

int32_t 
Calendar::getMinimum(EDateFields field) const {
    return getLimit((UCalendarDateFields) field,UCAL_LIMIT_MINIMUM);
}

int32_t
Calendar::getMinimum(UCalendarDateFields field) const
{
    return getLimit(field,UCAL_LIMIT_MINIMUM);
}

// -------------------------------------
int32_t
Calendar::getMaximum(EDateFields field) const
{
    return getLimit((UCalendarDateFields) field,UCAL_LIMIT_MAXIMUM);
}

int32_t
Calendar::getMaximum(UCalendarDateFields field) const
{
    return getLimit(field,UCAL_LIMIT_MAXIMUM);
}

// -------------------------------------
int32_t
Calendar::getGreatestMinimum(EDateFields field) const
{
    return getLimit((UCalendarDateFields)field,UCAL_LIMIT_GREATEST_MINIMUM);
}

int32_t
Calendar::getGreatestMinimum(UCalendarDateFields field) const
{
    return getLimit(field,UCAL_LIMIT_GREATEST_MINIMUM);
}

// -------------------------------------
int32_t
Calendar::getLeastMaximum(EDateFields field) const
{
    return getLimit((UCalendarDateFields) field,UCAL_LIMIT_LEAST_MAXIMUM);
}

int32_t
Calendar::getLeastMaximum(UCalendarDateFields field) const
{
    return getLimit( field,UCAL_LIMIT_LEAST_MAXIMUM);
}

// -------------------------------------
int32_t 
Calendar::getActualMinimum(EDateFields field, UErrorCode& status) const
{
    return getActualMinimum((UCalendarDateFields) field, status);
}

int32_t Calendar::getLimit(UCalendarDateFields field, ELimitType limitType) const {
    switch (field) {
    case UCAL_DAY_OF_WEEK:
    case UCAL_AM_PM:
    case UCAL_HOUR:
    case UCAL_HOUR_OF_DAY:
    case UCAL_MINUTE:
    case UCAL_SECOND:
    case UCAL_MILLISECOND:
    case UCAL_ZONE_OFFSET:
    case UCAL_DST_OFFSET:
    case UCAL_DOW_LOCAL:
    case UCAL_JULIAN_DAY:
    case UCAL_MILLISECONDS_IN_DAY:
        return kCalendarLimits[field][limitType];
    default:
        return handleGetLimit(field, limitType);
    }
}


int32_t
Calendar::getActualMinimum(UCalendarDateFields field, UErrorCode& status) const
{
    int32_t fieldValue = getGreatestMinimum(field);
    int32_t endValue = getMinimum(field);

    // if we know that the minimum value is always the same, just return it
    if (fieldValue == endValue) {
        return fieldValue;
    }

    // clone the calendar so we don't mess with the real one, and set it to
    // accept anything for the field values
    Calendar *work = (Calendar*)this->clone();
    work->setLenient(TRUE);

    // now try each value from getLeastMaximum() to getMaximum() one by one until
    // we get a value that normalizes to another value.  The last value that
    // normalizes to itself is the actual minimum for the current date
    int32_t result = fieldValue;

    do {
        work->set(field, fieldValue);
        if (work->get(field, status) != fieldValue) {
            break;
        } 
        else {
            result = fieldValue;
            fieldValue--;
        }
    } while (fieldValue >= endValue);

    delete work;

    /* Test for buffer overflows */
    if(U_FAILURE(status)) {
        return 0;
    }
    return result;
}

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



/**
 * Ensure that each field is within its valid range by calling {@link
 * #validateField(int)} on each field that has been set.  This method
 * should only be called if this calendar is not lenient.
 * @see #isLenient
 * @see #validateField(int)
 * @draft ICU 2.8
 */
void Calendar::validateFields(UErrorCode &status) {
  for (int32_t field = 0; U_SUCCESS(status) && (field < UCAL_FIELD_COUNT); field++) {
    if (isSet((UCalendarDateFields)field)) {
      validateField((UCalendarDateFields)field, status);
    }
  }
}

/**
 * Validate a single field of this calendar.  Subclasses should
 * override this method to validate any calendar-specific fields.
 * Generic fields can be handled by
 * <code>Calendar.validateField()</code>.
 * @see #validateField(int, int, int)
 * @draft ICU 2.8
 */
void Calendar::validateField(UCalendarDateFields field, UErrorCode &status) {
  int32_t y;
  switch (field) {
  case UCAL_DAY_OF_MONTH:
    y = handleGetExtendedYear();
    validateField(field, 1, handleGetMonthLength(y, internalGet(UCAL_MONTH)), status);
    break;
  case UCAL_DAY_OF_YEAR:
    y = handleGetExtendedYear();
    validateField(field, 1, handleGetYearLength(y), status);
    break;
  case UCAL_DAY_OF_WEEK_IN_MONTH:
    if (internalGet(field) == 0) {
#if defined (U_DEBUG_CAL)
          fprintf(stderr, "%s:%d: ILLEGAL ARG because DOW in month cannot be 0\n", 
                  __FILE__, __LINE__);
#endif
      status = U_ILLEGAL_ARGUMENT_ERROR; // "DAY_OF_WEEK_IN_MONTH cannot be zero"
      return;
    }
    validateField(field, getMinimum(field), getMaximum(field), status);
    break;
  default:
    validateField(field, getMinimum(field), getMaximum(field), status);
    break;
  }
}

/**
 * Validate a single field of this calendar given its minimum and
 * maximum allowed value.  If the field is out of range, throw a
 * descriptive <code>IllegalArgumentException</code>.  Subclasses may
 * use this method in their implementation of {@link
 * #validateField(int)}.
 * @draft ICU 2.8
 */
void Calendar::validateField(UCalendarDateFields field, int32_t min, int32_t max, UErrorCode& status)
{
  int32_t value = fFields[field];
  if (value < min || value > max) {
#if defined (U_DEBUG_CAL)
          fprintf(stderr, "%s:%d: ILLEGAL ARG because of field %s out of range %d..%d  at %d\n", 
                  __FILE__, __LINE__,fldName(field),min,max,value);
#endif
    status = U_ILLEGAL_ARGUMENT_ERROR;
    return;
  }
}

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

const UFieldResolutionTable* Calendar::getFieldResolutionTable() const {
  return kDatePrecedence;
}


UCalendarDateFields Calendar::newerField(UCalendarDateFields defaultField, UCalendarDateFields alternateField) const
{
  if (fStamp[alternateField] > fStamp[defaultField]) {
    return alternateField;
  }
  return defaultField;
}

UCalendarDateFields Calendar::resolveFields(const UFieldResolutionTable* precedenceTable) {
  int32_t bestField = UCAL_FIELD_COUNT;
  for (int32_t g=0; precedenceTable[g][0][0] != -1 && (bestField == UCAL_FIELD_COUNT); ++g) {
    int32_t bestStamp = kUnset;
    for (int32_t l=0; precedenceTable[g][l][0] != -1; ++l) {
      int32_t lineStamp = kUnset;
      // Skip over first entry if it is negative
      for (int32_t i=((precedenceTable[g][l][0]>=kResolveRemap)?1:0); precedenceTable[g][l][i]!=-1; ++i) {
        int32_t s = fStamp[precedenceTable[g][l][i]];
        // If any field is unset then don't use this line
        if (s == kUnset) {
          goto linesInGroup;
        } else if(s > lineStamp) {
          lineStamp = s;
        }
      }
      // Record new maximum stamp & field no.
      if (lineStamp > bestStamp) {
        bestStamp = lineStamp;
        bestField = precedenceTable[g][l][0]; // First field refers to entire line
      }
    linesInGroup:
      ;
    }
  }
  return (UCalendarDateFields)( (bestField>=kResolveRemap)?(bestField&(kResolveRemap-1)):bestField  );
}

const UFieldResolutionTable Calendar::kDatePrecedence[] =
  { 
    {
      { UCAL_DAY_OF_MONTH, kResolveSTOP },
      { UCAL_WEEK_OF_YEAR, UCAL_DAY_OF_WEEK, kResolveSTOP },
      { UCAL_WEEK_OF_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP },
      { UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP },
      { UCAL_WEEK_OF_YEAR, UCAL_DOW_LOCAL, kResolveSTOP },
      { UCAL_WEEK_OF_MONTH, UCAL_DOW_LOCAL, kResolveSTOP },
      { UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DOW_LOCAL, kResolveSTOP },
      { UCAL_DAY_OF_YEAR, kResolveSTOP },
      { kResolveRemap | UCAL_DAY_OF_MONTH, UCAL_YEAR, kResolveSTOP },  // if YEAR is set over YEAR_WOY use DAY_OF_MONTH
      { kResolveRemap | UCAL_WEEK_OF_YEAR, UCAL_YEAR_WOY, kResolveSTOP },  // if YEAR_WOY is set,  calc based on WEEK_OF_YEAR
      { kResolveSTOP }
    },
    {
      { UCAL_WEEK_OF_YEAR, kResolveSTOP },
      { UCAL_WEEK_OF_MONTH, kResolveSTOP },
      { UCAL_DAY_OF_WEEK_IN_MONTH, kResolveSTOP },
      { kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP },
      { kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DOW_LOCAL, kResolveSTOP },
      { kResolveSTOP }
    }, 
    {{kResolveSTOP}}
  };


const UFieldResolutionTable Calendar::kDOWPrecedence[] = 
{
  {
    { UCAL_DAY_OF_WEEK,kResolveSTOP, kResolveSTOP },
    { UCAL_DOW_LOCAL,kResolveSTOP, kResolveSTOP },
    {kResolveSTOP}
  },
  {{kResolveSTOP}}
};

// precedence for calculating a year
const UFieldResolutionTable Calendar::kYearPrecedence[] = 
{
  {
    { UCAL_YEAR, kResolveSTOP },
    { UCAL_EXTENDED_YEAR, kResolveSTOP },
    { UCAL_YEAR_WOY, UCAL_WEEK_OF_YEAR, kResolveSTOP },  // YEAR_WOY is useless without WEEK_OF_YEAR
    { kResolveSTOP }
  },
  {{kResolveSTOP}}
};


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


void Calendar::computeTime(UErrorCode& status) {
  if (!isLenient()) {
    validateFields(status);
  }

  // Compute the Julian day
  int32_t julianDay = computeJulianDay();

  double millis = Grego::julianDayToMillis(julianDay);

#if defined (U_DEBUG_CAL)
  //  int32_t julianInsanityCheck =  (int32_t)Math::floorDivide(millis, kOneDay);
  //  julianInsanityCheck += kEpochStartAsJulianDay;
  //  if(1 || julianInsanityCheck != julianDay) {
  //    fprintf(stderr, "%s:%d- D'oh- computed jules %d, to mills (%s)%.lf, recomputed %d\n",
  //            __FILE__, __LINE__, julianDay, millis<0.0?"NEG":"", millis, julianInsanityCheck);
  //  }
#endif

  int32_t millisInDay;

  // We only use MILLISECONDS_IN_DAY if it has been set by the user.
  // This makes it possible for the caller to set the calendar to a
  // time and call clear(MONTH) to reset the MONTH to January.  This
  // is legacy behavior.  Without this, clear(MONTH) has no effect,
  // since the internally set JULIAN_DAY is used.
  if (fStamp[UCAL_MILLISECONDS_IN_DAY] >= ((int32_t)kMinimumUserStamp) &&
      newestStamp(UCAL_AM_PM, UCAL_MILLISECOND, kUnset) <= fStamp[UCAL_MILLISECONDS_IN_DAY]) {
    millisInDay = internalGet(UCAL_MILLISECONDS_IN_DAY);
  } else {
    millisInDay = computeMillisInDay();
  }
  
  // Compute the time zone offset and DST offset.  There are two potential
  // ambiguities here.  We'll assume a 2:00 am (wall time) switchover time
  // for discussion purposes here.
  // 1. The transition into DST.  Here, a designated time of 2:00 am - 2:59 am
  //    can be in standard or in DST depending.  However, 2:00 am is an invalid
  //    representation (the representation jumps from 1:59:59 am Std to 3:00:00 am DST).
  //    We assume standard time.
  // 2. The transition out of DST.  Here, a designated time of 1:00 am - 1:59 am
  //    can be in standard or DST.  Both are valid representations (the rep
  //    jumps from 1:59:59 DST to 1:00:00 Std).
  //    Again, we assume standard time.
  // We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET
  // or DST_OFFSET fields; then we use those fields.
  if (fStamp[UCAL_ZONE_OFFSET] >= ((int32_t)kMinimumUserStamp) ||
      fStamp[UCAL_DST_OFFSET] >= ((int32_t)kMinimumUserStamp)) {
    millisInDay -= internalGet(UCAL_ZONE_OFFSET) + internalGet(UCAL_DST_OFFSET);
  } else {
    millisInDay -= computeZoneOffset(millis, millisInDay,status);
  }
  
  internalSetTime(millis + millisInDay);
}

/**
 * Compute the milliseconds in the day from the fields.  This is a
 * value from 0 to 23:59:59.999 inclusive, unless fields are out of
 * range, in which case it can be an arbitrary value.  This value
 * reflects local zone wall time.
 * @stable ICU 2.0
 */
int32_t Calendar::computeMillisInDay() {
  // Do the time portion of the conversion.
  
  int32_t millisInDay = 0;
  
  // Find the best set of fields specifying the time of day.  There
  // are only two possibilities here; the HOUR_OF_DAY or the
  // AM_PM and the HOUR.
  int32_t hourOfDayStamp = fStamp[UCAL_HOUR_OF_DAY];
  int32_t hourStamp = (fStamp[UCAL_HOUR] > fStamp[UCAL_AM_PM])?fStamp[UCAL_HOUR]:fStamp[UCAL_AM_PM];
  int32_t bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp;
  
  // Hours
  if (bestStamp != kUnset) {
    if (bestStamp == hourOfDayStamp) {
      // Don't normalize here; let overflow bump into the next period.
      // This is consistent with how we handle other fields.
      millisInDay += internalGet(UCAL_HOUR_OF_DAY);
    } else {
      // Don't normalize here; let overflow bump into the next period.
      // This is consistent with how we handle other fields.
      millisInDay += internalGet(UCAL_HOUR);
      millisInDay += 12 * internalGet(UCAL_AM_PM); // Default works for unset AM_PM
    }
  }
  
  // We use the fact that unset == 0; we start with millisInDay
  // == HOUR_OF_DAY.
  millisInDay *= 60;
  millisInDay += internalGet(UCAL_MINUTE); // now have minutes
  millisInDay *= 60;
  millisInDay += internalGet(UCAL_SECOND); // now have seconds
  millisInDay *= 1000;
  millisInDay += internalGet(MILLISECOND); // now have millis
  
  return millisInDay;
}

/**
 * This method can assume EXTENDED_YEAR has been set.
 * @param millis milliseconds of the date fields
 * @param millisInDay milliseconds of the time fields; may be out
 * or range.
 * @stable ICU 2.0
 */
int32_t Calendar::computeZoneOffset(double millis, int32_t millisInDay, UErrorCode &ec) {
  int32_t rawOffset, dstOffset;
  getTimeZone().getOffset(millis+millisInDay, TRUE, rawOffset, dstOffset, ec);
  return rawOffset + dstOffset;
  // Note: Because we pass in wall millisInDay, rather than
  // standard millisInDay, we interpret "1:00 am" on the day
  // of cessation of DST as "1:00 am Std" (assuming the time
  // of cessation is 2:00 am).
}

int32_t Calendar::computeJulianDay() 
{
  // We want to see if any of the date fields is newer than the
  // JULIAN_DAY.  If not, then we use JULIAN_DAY.  If so, then we do
  // the normal resolution.  We only use JULIAN_DAY if it has been
  // set by the user.  This makes it possible for the caller to set
  // the calendar to a time and call clear(MONTH) to reset the MONTH
  // to January.  This is legacy behavior.  Without this,
  // clear(MONTH) has no effect, since the internally set JULIAN_DAY
  // is used.
  if (fStamp[UCAL_JULIAN_DAY] >= (int32_t)kMinimumUserStamp) {
    int32_t bestStamp = newestStamp(UCAL_ERA, UCAL_DAY_OF_WEEK_IN_MONTH, kUnset);
    bestStamp = newestStamp(UCAL_YEAR_WOY, UCAL_EXTENDED_YEAR, bestStamp);
    if (bestStamp <= fStamp[UCAL_JULIAN_DAY]) {
      return internalGet(UCAL_JULIAN_DAY);
    }
  }

  UCalendarDateFields bestField = resolveFields(getFieldResolutionTable());
  if (bestField == UCAL_FIELD_COUNT) {
    bestField = UCAL_DAY_OF_MONTH;
  }

  return handleComputeJulianDay(bestField);
}

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

int32_t Calendar::handleComputeJulianDay(UCalendarDateFields bestField)  {
  UBool useMonth = (bestField == UCAL_DAY_OF_MONTH ||
                    bestField == UCAL_WEEK_OF_MONTH ||
                    bestField == UCAL_DAY_OF_WEEK_IN_MONTH);
  int32_t year;

  if (bestField == UCAL_WEEK_OF_YEAR) {
    year = internalGet(UCAL_YEAR_WOY, handleGetExtendedYear());
    internalSet(UCAL_EXTENDED_YEAR, year);
  } else {
    year = handleGetExtendedYear();
    internalSet(UCAL_EXTENDED_YEAR, year);
  }

#if defined (U_DEBUG_CAL) 
  fprintf(stderr, "%s:%d - bf= %s - y=%d\n", __FILE__, __LINE__, fldName(bestField), year);
#endif 

  // Get the Julian day of the day BEFORE the start of this year.
  // If useMonth is true, get the day before the start of the month.
  
  // give calendar subclass a chance to have a default 'first' month
  int8_t month;

  if(isSet(UCAL_MONTH)) {
    month = (int8_t)internalGet(UCAL_MONTH);
  } else {
    month = (int8_t)getDefaultMonthInYear();
  }

  int32_t julianDay = handleComputeMonthStart(year, useMonth ? month : 0, useMonth);

  if (bestField == UCAL_DAY_OF_MONTH) {

    // give calendar subclass a chance to have a default 'first' dom
    int32_t dayOfMonth;
    if(isSet(UCAL_DAY_OF_MONTH)) {
      dayOfMonth = internalGet(UCAL_DAY_OF_MONTH,1);
    } else {
      dayOfMonth = getDefaultDayInMonth(month);
    }
    return julianDay + dayOfMonth;
  }
  
  if (bestField == UCAL_DAY_OF_YEAR) {
    return julianDay + internalGet(UCAL_DAY_OF_YEAR);
  }
  
  int32_t firstDayOfWeek = getFirstDayOfWeek(); // Localized fdw
  
  // At this point julianDay is the 0-based 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). (or it is before the month we are in, if useMonth is True)
  
  // At this point we need to process the WEEK_OF_MONTH or
  // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH.
  // First, perform initial shared computations.  These locate the
  // first week of the period.
  
  // Get the 0-based localized DOW of day one of the month or year.
  // Valid range 0..6.
  int32_t first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek;
  if (first < 0) {
    first += 7;
  }

  int32_t dowLocal = getLocalDOW();
  
  // Find the first target DOW (dowLocal) in the month or year.
  // Actually, it may be just before the first of the month or year.
  // It will be an integer from -5..7.
  int32_t date = 1 - first + dowLocal;
  
  if (bestField == UCAL_DAY_OF_WEEK_IN_MONTH) {
    // Adjust the target DOW to be in the month or year.
    if (date < 1) {
      date += 7;
    }
    
    // The only trickiness occurs if the day-of-week-in-month is
    // negative.
    int32_t dim = internalGet(UCAL_DAY_OF_WEEK_IN_MONTH, 1);
    if (dim >= 0) {
      date += 7*(dim - 1);
      
    } else {
      // Move date to the last of this day-of-week in this month,
      // then back up as needed.  If dim==-1, we don't back up at
      // all.  If dim==-2, we back up once, etc.  Don't back up
      // past the first of the given day-of-week in this month.
      // Note that we handle -2, -3, etc. correctly, even though
      // values < -1 are technically disallowed.
      int32_t m = internalGet(UCAL_MONTH, UCAL_JANUARY);
      int32_t monthLength = handleGetMonthLength(year, m);
      date += ((monthLength - date) / 7 + dim + 1) * 7;
    }
  } else {
#if defined (U_DEBUG_CAL) 
    fprintf(stderr, "%s:%d - bf= %s\n", __FILE__, __LINE__, fldName(bestField));
#endif 

    if(bestField == UCAL_WEEK_OF_YEAR) {  // ------------------------------------- WOY -------------
      if(!isSet(UCAL_YEAR_WOY) ||  // YWOY not set at all or
         ( (resolveFields(kYearPrecedence) != UCAL_YEAR_WOY) // YWOY doesn't have precedence
           && (fStamp[UCAL_YEAR_WOY]!=kInternallySet) ) ) { // (excluding where all fields are internally set - then YWOY is used)
        // need to be sure to stay in 'real' year.
        int32_t woy = internalGet(bestField);

        int32_t nextJulianDay = handleComputeMonthStart(year+1, 0, FALSE); // jd of day before jan 1
        int32_t nextFirst = julianDayToDayOfWeek(nextJulianDay + 1) - firstDayOfWeek; 
        
        if (nextFirst < 0) { // 0..6 ldow of Jan 1
          nextFirst += 7;
        }

        if(woy==1) {  // FIRST WEEK ---------------------------------
#if defined (U_DEBUG_CAL) 
          fprintf(stderr, "%s:%d - woy=%d, yp=%d, nj(%d)=%d, nf=%d", __FILE__, __LINE__, 
                  internalGet(bestField), resolveFields(kYearPrecedence), year+1, 
                  nextJulianDay, nextFirst);
          
          fprintf(stderr, " next: %d DFW,  min=%d   \n", (7-nextFirst), getMinimalDaysInFirstWeek() );
#endif 
          
          // nextFirst is now the localized DOW of Jan 1  of y-woy+1
          if((nextFirst > 0) &&   // Jan 1 starts on FDOW
             (7-nextFirst) >= getMinimalDaysInFirstWeek()) { // or enough days in the week
            // Jan 1 of (yearWoy+1) is in yearWoy+1 - recalculate JD to next year
#if defined (U_DEBUG_CAL) 
            fprintf(stderr, "%s:%d - was going to move JD from %d to %d [d%d]\n", __FILE__, __LINE__, 
                    julianDay, nextJulianDay, (nextJulianDay-julianDay));
#endif 
            julianDay = nextJulianDay;
            
            // recalculate 'first' [0-based local dow of jan 1]
            first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek;
            if (first < 0) {
              first += 7;
            }
            // recalculate date.
            date = 1 - first + dowLocal;
          }
        } else if(woy>=getLeastMaximum(bestField)) {          
          // could be in the last week- find out if this JD would overstep
          int32_t testDate = date;
          if ((7 - first) < getMinimalDaysInFirstWeek()) {
            testDate += 7;
          }
          
          // Now adjust for the week number.
          testDate += 7 * (woy - 1);
          
#if defined (U_DEBUG_CAL) 
          fprintf(stderr, "%s:%d - y=%d, y-1=%d doy%d, njd%d (C.F. %d)\n",
                  __FILE__, __LINE__, year, year-1, testDate, julianDay+testDate, nextJulianDay);
#endif
          if(julianDay+testDate > nextJulianDay) { // is it past Dec 31?  (nextJulianDay is day BEFORE year+1's  Jan 1)
            // Fire up the calculating engines.. retry YWOY = (year-1)
            julianDay = handleComputeMonthStart(year-1, 0, FALSE); // jd before Jan 1 of previous year
            first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek; // 0 based local dow   of first week
            
            if(first < 0) { // 0..6
              first += 7;
            }
            date = 1 - first + dowLocal;

#if defined (U_DEBUG_CAL) 
            fprintf(stderr, "%s:%d - date now %d, jd%d, ywoy%d\n",
                    __FILE__, __LINE__, date, julianDay, year-1);
#endif

            
          } /* correction needed */
        } /* leastmaximum */
      } /* resolvefields(year) != year_woy */
    } /* bestfield != week_of_year */
    
    // assert(bestField == WEEK_OF_MONTH || bestField == WEEK_OF_YEAR)
    // Adjust for minimal days in first week
    if ((7 - first) < getMinimalDaysInFirstWeek()) {
      date += 7;
    }
    
    // Now adjust for the week number.
    date += 7 * (internalGet(bestField) - 1);
  }
  
  return julianDay + date;
}

int32_t
Calendar::getDefaultMonthInYear() 
{
    return 0;
}

int32_t
Calendar::getDefaultDayInMonth(int32_t /*month*/) 
{
    return 1;
}


int32_t Calendar::getLocalDOW()
{
  // Get zero-based localized DOW, valid range 0..6.  This is the DOW
  // we are looking for.
  int32_t dowLocal = 0;
  switch (resolveFields(kDOWPrecedence)) {
  case DAY_OF_WEEK:
    dowLocal = internalGet(UCAL_DAY_OF_WEEK) - fFirstDayOfWeek;
    break;
  case DOW_LOCAL:
    dowLocal = internalGet(UCAL_DOW_LOCAL) - 1;
    break;
  default:
    break;
  }
  dowLocal = dowLocal % 7;
  if (dowLocal < 0) {
    dowLocal += 7;
  }
  return dowLocal;
}

int32_t Calendar::handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t woy)
{
  // We have UCAL_YEAR_WOY and UCAL_WEEK_OF_YEAR - from those, determine 
  // what year we fall in, so that other code can set it properly.
  // (code borrowed from computeWeekFields and handleComputeJulianDay)
  //return yearWoy;

   // First, we need a reliable DOW.
   UCalendarDateFields bestField = resolveFields(kDatePrecedence); // !! Note: if subclasses have a different table, they should override handleGetExtendedYearFromWeekFields 

   // Now, a local DOW
   int32_t dowLocal = getLocalDOW(); // 0..6
   int32_t firstDayOfWeek = getFirstDayOfWeek(); // Localized fdw
   int32_t jan1Start = handleComputeMonthStart(yearWoy, 0, FALSE);
   int32_t nextJan1Start = handleComputeMonthStart(yearWoy+1, 0, FALSE); // next year's Jan1 start
   
   // At this point julianDay is the 0-based 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). (or it is before the month we are in, if useMonth is True)
   
   // At this point we need to process the WEEK_OF_MONTH or
   // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH.
   // First, perform initial shared computations.  These locate the
   // first week of the period.
   
   // Get the 0-based localized DOW of day one of the month or year.
   // Valid range 0..6.
   int32_t first = julianDayToDayOfWeek(jan1Start + 1) - firstDayOfWeek;
   if (first < 0) {
     first += 7;
   }
   int32_t nextFirst = julianDayToDayOfWeek(nextJan1Start + 1) - firstDayOfWeek;
   if (nextFirst < 0) {
     nextFirst += 7;
   }

   int32_t minDays = getMinimalDaysInFirstWeek();
   UBool jan1InPrevYear = FALSE;  // January 1st in the year of WOY is the 1st week?  (i.e. first week is < minimal )
   UBool nextJan1InPrevYear = FALSE; // January 1st of Year of WOY + 1 is in the first week? 

   if((7 - first) < minDays) { 
     jan1InPrevYear = TRUE;
   }

   if((7 - nextFirst) < minDays) {
     nextJan1InPrevYear = TRUE;
   }
   
   switch(bestField) {
   case UCAL_WEEK_OF_YEAR:
     if(woy == 1) {
       if(jan1InPrevYear == TRUE) {
         // the first week of January is in the previous year
         // therefore WOY1 is always solidly within yearWoy
         return yearWoy;
       } else {
         // First WOY is split between two years
         if( dowLocal < first) { // we are prior to Jan 1
           return yearWoy-1; // previous year
         } else {
           return yearWoy; // in this year
         }
       }
     } else if(woy >= getLeastMaximum(bestField)) {  
       // we _might_ be in the last week.. 
       int32_t jd =  // Calculate JD of our target day:
         jan1Start +  // JD of Jan 1
         (7-first) + //  days in the first week (Jan 1.. )
         (woy-1)*7 + // add the weeks of the year
         dowLocal;   // the local dow (0..6) of last week
       if(jan1InPrevYear==FALSE) {
         jd -= 7; // woy already includes Jan 1's week.
       }
       
       if( (jd+1) >= nextJan1Start ) {
         // we are in week 52 or 53 etc. - actual year is yearWoy+1
         return yearWoy+1;
       } else {
         // still in yearWoy;
         return yearWoy;
       }
     } else {
       // we're not possibly in the last week -must be ywoy
       return yearWoy;
     }
     break;

    case UCAL_DATE:
     if((internalGet(UCAL_MONTH)==0) &&
        (woy >= getLeastMaximum(UCAL_WEEK_OF_YEAR))) {
       return yearWoy+1; // month 0, late woy = in the next year
     } else if(woy==1) {
       //if(nextJan1InPrevYear) {
       if(internalGet(UCAL_MONTH)==0) {
         return yearWoy;
       } else {
         return yearWoy-1;
       }
       //}
     }

     //(internalGet(UCAL_DATE) <= (7-first)) /* && in minDow  */ ) {
     //within 1st week and in this month.. 
     //return yearWoy+1;
     return yearWoy;
     break;

   default: // assume the year is appropriate
     return yearWoy;
     break;
   }

#if defined (U_DEBUG_CAL) 
   fprintf(stderr, "%s:%d - forgot a return on field %s\n", __FILE__, __LINE__, fldName(bestField));
#endif 

   return yearWoy;
}

int32_t Calendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const
{
    return handleComputeMonthStart(extendedYear, month+1, TRUE) -
        handleComputeMonthStart(extendedYear, month, TRUE);
}

int32_t Calendar::handleGetYearLength(int32_t eyear) const  {
    return handleComputeMonthStart(eyear+1, 0, FALSE) -
            handleComputeMonthStart(eyear, 0, FALSE);
}

int32_t
Calendar::getActualMaximum(UCalendarDateFields field, UErrorCode& status) const
{
    int32_t result;
    switch (field) {
    case UCAL_DATE:
        {
            if(U_FAILURE(status)) return 0;
            Calendar *cal = clone();
            if(!cal) { status = U_MEMORY_ALLOCATION_ERROR; return 0; }
            cal->prepareGetActual(field,FALSE,status);
            result = handleGetMonthLength(cal->get(UCAL_EXTENDED_YEAR, status), cal->get(UCAL_MONTH, status));
            delete cal;
        }
        break;

    case UCAL_DAY_OF_YEAR:
        {
            if(U_FAILURE(status)) return 0;
            Calendar *cal = clone();
            if(!cal) { status = U_MEMORY_ALLOCATION_ERROR; return 0; }
            cal->prepareGetActual(field,FALSE,status);
            result = handleGetYearLength(cal->get(UCAL_EXTENDED_YEAR, status));
            delete cal;
        }
        break;

    case DAY_OF_WEEK:
    case AM_PM:
    case HOUR:
    case HOUR_OF_DAY:
    case MINUTE:
    case SECOND:
    case MILLISECOND:
    case ZONE_OFFSET:
    case DST_OFFSET:
    case DOW_LOCAL:
    case UCAL_JULIAN_DAY:
    case UCAL_MILLISECONDS_IN_DAY:
        // These fields all have fixed minima/maxima
        result = getMaximum(field);
        break;

    default:
        // For all other fields, do it the hard way....
        result = getActualHelper(field, getLeastMaximum(field), getMaximum(field),status);
        break;
    }
    return result;
}


/**
* Prepare this calendar for computing the actual minimum or maximum.
* This method modifies this calendar's fields; it is called on a
* temporary calendar.
*
* <p>Rationale: The semantics of getActualXxx() is to return the
* maximum or minimum value that the given field can take, taking into
* account other relevant fields.  In general these other fields are
* larger fields.  For example, when computing the actual maximum
* DATE, the current value of DATE itself is ignored,
* as is the value of any field smaller.
*
* <p>The time fields all have fixed minima and maxima, so we don't
* need to worry about them.  This also lets us set the
* MILLISECONDS_IN_DAY to zero to erase any effects the time fields
* might have when computing date fields.
*
* <p>DAY_OF_WEEK is adjusted specially for the WEEK_OF_MONTH and
* WEEK_OF_YEAR fields to ensure that they are computed correctly.
* @internal
*/
void Calendar::prepareGetActual(UCalendarDateFields field, UBool isMinimum, UErrorCode &status)
 {
    set(UCAL_MILLISECONDS_IN_DAY, 0);

    switch (field) {
    case UCAL_YEAR:
    case UCAL_YEAR_WOY:
    case UCAL_EXTENDED_YEAR:
        set(UCAL_DAY_OF_YEAR, getGreatestMinimum(UCAL_DAY_OF_YEAR));
        break;

    case UCAL_MONTH:
        set(UCAL_DATE, getGreatestMinimum(UCAL_DATE));
        break;

    case UCAL_DAY_OF_WEEK_IN_MONTH:
        // For dowim, the maximum occurs for the DOW of the first of the
        // month.
        set(UCAL_DATE, 1);
        set(UCAL_DAY_OF_WEEK, get(UCAL_DAY_OF_WEEK, status)); // Make this user set
        break;

    case UCAL_WEEK_OF_MONTH:
    case UCAL_WEEK_OF_YEAR:
        // If we're counting weeks, set the day of the week to either the
        // first or last localized DOW.  We know the last week of a month
        // or year will contain the first day of the week, and that the
        // first week will contain the last DOW.
        {
            int32_t dow = fFirstDayOfWeek;
            if (isMinimum) {
                dow = (dow + 6) % 7; // set to last DOW
                if (dow < UCAL_SUNDAY) {
                    dow += 7;
                }
            }
#if defined (U_DEBUG_CAL) 
            fprintf(stderr, "prepareGetActualHelper(WOM/WOY) - dow=%d\n", dow);
#endif
            set(UCAL_DAY_OF_WEEK, dow);
        }
        break;
    default:
	;
    }

    // Do this last to give it the newest time stamp
    set(field, getGreatestMinimum(field));
}

int32_t Calendar::getActualHelper(UCalendarDateFields field, int32_t startValue, int32_t endValue, UErrorCode &status) const
{
#if defined (U_DEBUG_CAL) 
  fprintf(stderr, "getActualHelper(%d,%d .. %d, %s)\n", field, startValue, endValue, u_errorName(status));
#endif
    if (startValue == endValue) {
        // if we know that the maximum value is always the same, just return it
        return startValue;
    }

    int32_t delta = (endValue > startValue) ? 1 : -1;

    // clone the calendar so we don't mess with the real one, and set it to
    // accept anything for the field values
    if(U_FAILURE(status)) return startValue;
    Calendar *work = clone();
    if(!work) { status = U_MEMORY_ALLOCATION_ERROR; return startValue; }
    work->setLenient(TRUE);
#if defined (U_DEBUG_CAL) 
    fprintf(stderr, "%s:%d - getActualHelper - %s\n", __FILE__, __LINE__, u_errorName(status));
#endif 
   work->prepareGetActual(field, delta < 0, status);
#if defined (U_DEBUG_CAL) 
    fprintf(stderr, "%s:%d - getActualHelper - %s\n", __FILE__, __LINE__, u_errorName(status));
#endif

    // now try each value from the start to the end one by one until
    // we get a value that normalizes to another value.  The last value that
    // normalizes to itself is the actual maximum for the current date
    int32_t result = startValue;
    do {
#if defined (U_DEBUG_CAL) 
    fprintf(stderr, "%s:%d - getActualHelper - %s\n", __FILE__, __LINE__, u_errorName(status));
#endif
        work->set(field, startValue);
#if defined (U_DEBUG_CAL) 
        fprintf(stderr, "%s:%d - getActualHelper - %s (set to %d)\n", __FILE__, __LINE__, u_errorName(status), startValue);
#endif
        if (work->get(field, status) != startValue) {
#if defined (U_DEBUG_CAL) 
          fprintf(stderr, "getActualHelper(fld %d) - got  %d (not %d), BREAK - %s\n", field, work->get(field,status), startValue, u_errorName(status));
#endif
            break;
        } else {
            result = startValue;
            startValue += delta;
#if defined (U_DEBUG_CAL) 
            fprintf(stderr, "getActualHelper(%d)  result=%d (start), start += %d to %d\n", field, result, delta, startValue);
#endif
        }
    } while (result != endValue && U_SUCCESS(status));
    delete work;
#if defined (U_DEBUG_CAL) 
    fprintf(stderr, "getActualHelper(%d) = %d\n", field, result);
#endif
    return result;
}




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

void
Calendar::setWeekCountData(const Locale& desiredLocale, const char *type, UErrorCode& status)
{
    // Read the week count data from the resource bundle.  This should
    // have the form:
    //
    //   DateTimeElements:intvector {
    //      1,    // first day of week
    //      1     // min days in week
    //   }
    //   Both have a range of 1..7


    if (U_FAILURE(status)) return;

    fFirstDayOfWeek = UCAL_SUNDAY;
    fMinimalDaysInFirstWeek = 1;

    CalendarData calData(desiredLocale, type, status);
    // If the resource data doesn't seem to be present at all, then use last-resort
    // hard-coded data.
    UResourceBundle *dateTimeElements = calData.getByKey(kDateTimeElements, status);

    if (U_FAILURE(status))
    {
#if defined (U_DEBUG_CALDATA)
      fprintf(stderr, " Failure loading dateTimeElements = %s\n", u_errorName(status));
#endif
        status = U_USING_FALLBACK_WARNING;
        return;
    }

    U_LOCALE_BASED(locBased, *this);
    locBased.setLocaleIDs(ures_getLocaleByType(dateTimeElements, ULOC_VALID_LOCALE, &status),
                          ures_getLocaleByType(dateTimeElements, ULOC_ACTUAL_LOCALE, &status));
    if (U_SUCCESS(status)) {
#if defined (U_DEBUG_CAL)
      fprintf(stderr, " Valid=%s, Actual=%s\n", validLocale, actualLocale);
#endif
        int32_t arrLen;
        const int32_t *dateTimeElementsArr = ures_getIntVector(dateTimeElements, &arrLen, &status);

        if(U_SUCCESS(status) && arrLen == 2
            && 1 <= dateTimeElementsArr[0] && dateTimeElementsArr[0] <= 7
            && 1 <= dateTimeElementsArr[1] && dateTimeElementsArr[1] <= 7)
        {
            fFirstDayOfWeek = (UCalendarDaysOfWeek)dateTimeElementsArr[0];
            fMinimalDaysInFirstWeek = (uint8_t)dateTimeElementsArr[1];
        }
        else {
            status = U_INVALID_FORMAT_ERROR;
        }
    }
    
    // do NOT close dateTimeElements
}

/**
 * Recompute the time and update the status fields isTimeSet
 * and areFieldsSet.  Callers should check isTimeSet and only
 * call this method if isTimeSet is false.
 */
void 
Calendar::updateTime(UErrorCode& status) 
{
    computeTime(status);
    if(U_FAILURE(status))
        return;
        
    // If we are lenient, we need to recompute the fields to normalize
    // the values.  Also, if we haven't set all the fields yet (i.e.,
    // in a newly-created object), we need to fill in the fields. [LIU]
    if (isLenient() || ! fAreAllFieldsSet) 
        fAreFieldsSet = FALSE;
    
    fIsTimeSet = TRUE;
    fAreFieldsVirtuallySet = FALSE;
}

Locale 
Calendar::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
    U_LOCALE_BASED(locBased, *this);
    return locBased.getLocale(type, status);
}

const char *
Calendar::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
    U_LOCALE_BASED(locBased, *this);
    return locBased.getLocaleID(type, status);
}

U_NAMESPACE_END

// INTERNAL - for cleanup
// clean up the astronomical data & cache
U_CFUNC UBool calendar_islamic_cleanup(void);
U_CFUNC UBool calendar_hebrew_cleanup(void);
U_CFUNC UBool calendar_astro_cleanup(void);

U_CFUNC UBool calendar_cleanup(void) {
  calendar_islamic_cleanup();
  calendar_hebrew_cleanup();
  calendar_astro_cleanup();
  if (gService) {
    delete gService;
    gService = NULL;
  }
  return TRUE;
}


#endif /* #if !UCONFIG_NO_FORMATTING */


//eof
