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 17U_NAMESPACE_BEGIN 18 19UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CopticCalendar) 20 21static const int32_t COPTIC_JD_EPOCH_OFFSET = 1824665; 22 23//------------------------------------------------------------------------- 24// Constructors... 25//------------------------------------------------------------------------- 26 27CopticCalendar::CopticCalendar(const Locale& aLocale, UErrorCode& success) 28: CECalendar(aLocale, success) 29{ 30} 31 32CopticCalendar::CopticCalendar (const CopticCalendar& other) 33: CECalendar(other) 34{ 35} 36 37CopticCalendar::~CopticCalendar() 38{ 39} 40 41Calendar* 42CopticCalendar::clone() const 43{ 44 return new CopticCalendar(*this); 45} 46 47const char* 48CopticCalendar::getType() const 49{ 50 return "coptic"; 51} 52 53//------------------------------------------------------------------------- 54// Calendar framework 55//------------------------------------------------------------------------- 56 57int32_t 58CopticCalendar::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 75void 76CopticCalendar::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 97const UDate CopticCalendar::fgSystemDefaultCentury = DBL_MIN; 98const int32_t CopticCalendar::fgSystemDefaultCenturyYear = -1; 99 100UDate CopticCalendar::fgSystemDefaultCenturyStart = DBL_MIN; 101int32_t CopticCalendar::fgSystemDefaultCenturyStartYear = -1; 102 103UDate 104CopticCalendar::defaultCenturyStart() const 105{ 106 initializeSystemDefaultCentury(); 107 108 // use defaultCenturyStart unless it's the flag value; 109 // then use systemDefaultCenturyStart 110 return fgSystemDefaultCenturyStart; 111} 112 113int32_t 114CopticCalendar::defaultCenturyStartYear() const 115{ 116 initializeSystemDefaultCentury(); 117 118 // use defaultCenturyStart unless it's the flag value; 119 // then use systemDefaultCenturyStart 120 return fgSystemDefaultCenturyStartYear; 121} 122 123void 124CopticCalendar::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 153int32_t 154CopticCalendar::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 168int32_t 169CopticCalendar::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 175U_NAMESPACE_END 176 177#endif /* #if !UCONFIG_NO_FORMATTING */ 178//eof 179