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