Home | History | Annotate | Download | only in i18n
      1 /*
      2  *******************************************************************************
      3  * Copyright (C) 2003-2008, International Business Machines Corporation and    *
      4  * others. All Rights Reserved.                                                *
      5  *******************************************************************************
      6  *
      7  * File TAIWNCAL.CPP
      8  *
      9  * Modification History:
     10  *  05/13/2003    srl     copied from gregocal.cpp
     11  *  06/29/2007    srl     copied from buddhcal.cpp
     12  *  05/12/2008    jce     modified to use calendar=roc per CLDR
     13  *
     14  */
     15 
     16 #include "unicode/utypes.h"
     17 
     18 #if !UCONFIG_NO_FORMATTING
     19 
     20 #include "taiwncal.h"
     21 #include "unicode/gregocal.h"
     22 #include "umutex.h"
     23 #include <float.h>
     24 
     25 U_NAMESPACE_BEGIN
     26 
     27 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TaiwanCalendar)
     28 
     29 static const int32_t kTaiwanEraStart = 1911;  // 1911 (Gregorian)
     30 
     31 static const int32_t kGregorianEpoch = 1970;
     32 
     33 TaiwanCalendar::TaiwanCalendar(const Locale& aLocale, UErrorCode& success)
     34 :   GregorianCalendar(aLocale, success)
     35 {
     36     setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly.
     37 }
     38 
     39 TaiwanCalendar::~TaiwanCalendar()
     40 {
     41 }
     42 
     43 TaiwanCalendar::TaiwanCalendar(const TaiwanCalendar& source)
     44 : GregorianCalendar(source)
     45 {
     46 }
     47 
     48 TaiwanCalendar& TaiwanCalendar::operator= ( const TaiwanCalendar& right)
     49 {
     50     GregorianCalendar::operator=(right);
     51     return *this;
     52 }
     53 
     54 Calendar* TaiwanCalendar::clone(void) const
     55 {
     56     return new TaiwanCalendar(*this);
     57 }
     58 
     59 const char *TaiwanCalendar::getType() const
     60 {
     61     return "roc";
     62 }
     63 
     64 int32_t TaiwanCalendar::handleGetExtendedYear()
     65 {
     66     // EXTENDED_YEAR in TaiwanCalendar is a Gregorian year
     67     // The default value of EXTENDED_YEAR is 1970 (Minguo 59)
     68     int32_t year = kGregorianEpoch;
     69 
     70     if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR
     71         && newerField(UCAL_EXTENDED_YEAR, UCAL_ERA) == UCAL_EXTENDED_YEAR) {
     72         year = internalGet(UCAL_EXTENDED_YEAR, kGregorianEpoch);
     73     } else {
     74         int32_t era = internalGet(UCAL_ERA, MINGUO);
     75         if(era == MINGUO) {
     76             year =     internalGet(UCAL_YEAR, 1) + kTaiwanEraStart;
     77         } else if(era == BEFORE_MINGUO) {
     78             year = 1 - internalGet(UCAL_YEAR, 1) + kTaiwanEraStart;
     79         }
     80     }
     81     return year;
     82 }
     83 
     84 void TaiwanCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
     85 {
     86     GregorianCalendar::handleComputeFields(julianDay, status);
     87     int32_t y = internalGet(UCAL_EXTENDED_YEAR) - kTaiwanEraStart;
     88     if(y>0) {
     89         internalSet(UCAL_ERA, MINGUO);
     90         internalSet(UCAL_YEAR, y);
     91     } else {
     92         internalSet(UCAL_ERA, BEFORE_MINGUO);
     93         internalSet(UCAL_YEAR, 1-y);
     94     }
     95 }
     96 
     97 int32_t TaiwanCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const
     98 {
     99     if(field == UCAL_ERA) {
    100         if(limitType == UCAL_LIMIT_MINIMUM || limitType == UCAL_LIMIT_GREATEST_MINIMUM) {
    101             return BEFORE_MINGUO;
    102         } else {
    103             return MINGUO;
    104         }
    105     } else {
    106         return GregorianCalendar::handleGetLimit(field,limitType);
    107     }
    108 }
    109 
    110 #if 0
    111 void TaiwanCalendar::timeToFields(UDate theTime, UBool quick, UErrorCode& status)
    112 {
    113     //Calendar::timeToFields(theTime, quick, status);
    114 
    115     int32_t era = internalGet(UCAL_ERA);
    116     int32_t year = internalGet(UCAL_YEAR);
    117 
    118     if(era == GregorianCalendar::BC) {
    119         year = 1-year;
    120         era = TaiwanCalendar::MINGUO;
    121     } else if(era == GregorianCalendar::AD) {
    122         era = TaiwanCalendar::MINGUO;
    123     } else {
    124         status = U_INTERNAL_PROGRAM_ERROR;
    125     }
    126 
    127     year = year - kTaiwanEraStart;
    128 
    129     internalSet(UCAL_ERA, era);
    130     internalSet(UCAL_YEAR, year);
    131 }
    132 #endif
    133 
    134 // default century
    135 const UDate     TaiwanCalendar::fgSystemDefaultCentury        = DBL_MIN;
    136 const int32_t   TaiwanCalendar::fgSystemDefaultCenturyYear    = -1;
    137 
    138 UDate           TaiwanCalendar::fgSystemDefaultCenturyStart       = DBL_MIN;
    139 int32_t         TaiwanCalendar::fgSystemDefaultCenturyStartYear   = -1;
    140 
    141 
    142 UBool TaiwanCalendar::haveDefaultCentury() const
    143 {
    144     return TRUE;
    145 }
    146 
    147 UDate TaiwanCalendar::defaultCenturyStart() const
    148 {
    149     return internalGetDefaultCenturyStart();
    150 }
    151 
    152 int32_t TaiwanCalendar::defaultCenturyStartYear() const
    153 {
    154     return internalGetDefaultCenturyStartYear();
    155 }
    156 
    157 UDate
    158 TaiwanCalendar::internalGetDefaultCenturyStart() const
    159 {
    160     // lazy-evaluate systemDefaultCenturyStart
    161     UBool needsUpdate;
    162     UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate);
    163 
    164     if (needsUpdate) {
    165         initializeSystemDefaultCentury();
    166     }
    167 
    168     // use defaultCenturyStart unless it's the flag value;
    169     // then use systemDefaultCenturyStart
    170 
    171     return fgSystemDefaultCenturyStart;
    172 }
    173 
    174 int32_t
    175 TaiwanCalendar::internalGetDefaultCenturyStartYear() const
    176 {
    177     // lazy-evaluate systemDefaultCenturyStartYear
    178     UBool needsUpdate;
    179     UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate);
    180 
    181     if (needsUpdate) {
    182         initializeSystemDefaultCentury();
    183     }
    184 
    185     // use defaultCenturyStart unless it's the flag value;
    186     // then use systemDefaultCenturyStartYear
    187 
    188     return    fgSystemDefaultCenturyStartYear;
    189 }
    190 
    191 void
    192 TaiwanCalendar::initializeSystemDefaultCentury()
    193 {
    194     // initialize systemDefaultCentury and systemDefaultCenturyYear based
    195     // on the current time.  They'll be set to 80 years before
    196     // the current time.
    197     UErrorCode status = U_ZERO_ERROR;
    198     TaiwanCalendar calendar(Locale("@calendar=roc"),status);
    199     if (U_SUCCESS(status))
    200     {
    201         calendar.setTime(Calendar::getNow(), status);
    202         calendar.add(UCAL_YEAR, -80, status);
    203         UDate    newStart =  calendar.getTime(status);
    204         int32_t  newYear  =  calendar.get(UCAL_YEAR, status);
    205         umtx_lock(NULL);
    206         if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury)
    207         {
    208             fgSystemDefaultCenturyStartYear = newYear;
    209             fgSystemDefaultCenturyStart = newStart;
    210         }
    211         umtx_unlock(NULL);
    212     }
    213     // We have no recourse upon failure unless we want to propagate the failure
    214     // out.
    215 }
    216 
    217 
    218 U_NAMESPACE_END
    219 
    220 #endif
    221