1 /* 2 ******************************************************************************* 3 * Copyright (C) 2003 - 2009, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 8 #include "unicode/utypes.h" 9 10 #if !UCONFIG_NO_FORMATTING 11 12 #include "umutex.h" 13 #include "coptccal.h" 14 #include "cecal.h" 15 #include <float.h> 16 17 U_NAMESPACE_BEGIN 18 19 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CopticCalendar) 20 21 static const int32_t COPTIC_JD_EPOCH_OFFSET = 1824665; 22 23 //------------------------------------------------------------------------- 24 // Constructors... 25 //------------------------------------------------------------------------- 26 27 CopticCalendar::CopticCalendar(const Locale& aLocale, UErrorCode& success) 28 : CECalendar(aLocale, success) 29 { 30 } 31 32 CopticCalendar::CopticCalendar (const CopticCalendar& other) 33 : CECalendar(other) 34 { 35 } 36 37 CopticCalendar::~CopticCalendar() 38 { 39 } 40 41 Calendar* 42 CopticCalendar::clone() const 43 { 44 return new CopticCalendar(*this); 45 } 46 47 const char* 48 CopticCalendar::getType() const 49 { 50 return "coptic"; 51 } 52 53 //------------------------------------------------------------------------- 54 // Calendar framework 55 //------------------------------------------------------------------------- 56 57 int32_t 58 CopticCalendar::handleGetExtendedYear() 59 { 60 int32_t eyear; 61 if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) { 62 eyear = internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1 63 } else { 64 // The year defaults to the epoch start, the era to CE 65 int32_t era = internalGet(UCAL_ERA, CE); 66 if (era == BCE) { 67 eyear = 1 - internalGet(UCAL_YEAR, 1); // Convert to extended year 68 } else { 69 eyear = internalGet(UCAL_YEAR, 1); // Default to year 1 70 } 71 } 72 return eyear; 73 } 74 75 void 76 CopticCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/) 77 { 78 int32_t eyear, month, day, era, year; 79 jdToCE(julianDay, getJDEpochOffset(), eyear, month, day); 80 81 if (eyear <= 0) { 82 era = BCE; 83 year = 1 - eyear; 84 } else { 85 era = CE; 86 year = eyear; 87 } 88 89 internalSet(UCAL_EXTENDED_YEAR, eyear); 90 internalSet(UCAL_ERA, era); 91 internalSet(UCAL_YEAR, year); 92 internalSet(UCAL_MONTH, month); 93 internalSet(UCAL_DATE, day); 94 internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day); 95 } 96 97 const UDate CopticCalendar::fgSystemDefaultCentury = DBL_MIN; 98 const int32_t CopticCalendar::fgSystemDefaultCenturyYear = -1; 99 100 UDate CopticCalendar::fgSystemDefaultCenturyStart = DBL_MIN; 101 int32_t CopticCalendar::fgSystemDefaultCenturyStartYear = -1; 102 103 UDate 104 CopticCalendar::defaultCenturyStart() const 105 { 106 initializeSystemDefaultCentury(); 107 108 // use defaultCenturyStart unless it's the flag value; 109 // then use systemDefaultCenturyStart 110 return fgSystemDefaultCenturyStart; 111 } 112 113 int32_t 114 CopticCalendar::defaultCenturyStartYear() const 115 { 116 initializeSystemDefaultCentury(); 117 118 // use defaultCenturyStart unless it's the flag value; 119 // then use systemDefaultCenturyStart 120 return fgSystemDefaultCenturyStartYear; 121 } 122 123 void 124 CopticCalendar::initializeSystemDefaultCentury() 125 { 126 // lazy-evaluate systemDefaultCenturyStart 127 UBool needsUpdate; 128 UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate); 129 130 if (!needsUpdate) { 131 return; 132 } 133 134 UErrorCode status = U_ZERO_ERROR; 135 136 CopticCalendar calendar(Locale("@calendar=coptic"), status); 137 if (U_SUCCESS(status)) { 138 calendar.setTime(Calendar::getNow(), status); 139 calendar.add(UCAL_YEAR, -80, status); 140 UDate newStart = calendar.getTime(status); 141 int32_t newYear = calendar.get(UCAL_YEAR, status); 142 { 143 umtx_lock(NULL); 144 fgSystemDefaultCenturyStartYear = newYear; 145 fgSystemDefaultCenturyStart = newStart; 146 umtx_unlock(NULL); 147 } 148 } 149 // We have no recourse upon failure unless we want to propagate the failure 150 // out. 151 } 152 153 int32_t 154 CopticCalendar::getJDEpochOffset() const 155 { 156 return COPTIC_JD_EPOCH_OFFSET; 157 } 158 159 160 #if 0 161 // We do not want to introduce this API in ICU4C. 162 // It was accidentally introduced in ICU4J as a public API. 163 164 //------------------------------------------------------------------------- 165 // Calendar system Conversion methods... 166 //------------------------------------------------------------------------- 167 168 int32_t 169 CopticCalendar::copticToJD(int32_t year, int32_t month, int32_t day) 170 { 171 return CECalendar::ceToJD(year, month, day, COPTIC_JD_EPOCH_OFFSET); 172 } 173 #endif 174 175 U_NAMESPACE_END 176 177 #endif /* #if !UCONFIG_NO_FORMATTING */ 178 //eof 179