|
1 /* |
|
2 ******************************************************************************* |
|
3 * Copyright (C) 2003 - 2013, 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 "ethpccal.h" |
|
14 #include "cecal.h" |
|
15 #include <float.h> |
|
16 |
|
17 U_NAMESPACE_BEGIN |
|
18 |
|
19 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EthiopicCalendar) |
|
20 |
|
21 //static const int32_t JD_EPOCH_OFFSET_AMETE_ALEM = -285019; |
|
22 static const int32_t JD_EPOCH_OFFSET_AMETE_MIHRET = 1723856; |
|
23 static const int32_t AMETE_MIHRET_DELTA = 5500; // 5501 - 1 (Amete Alem 5501 = Amete Mihret 1) |
|
24 |
|
25 //------------------------------------------------------------------------- |
|
26 // Constructors... |
|
27 //------------------------------------------------------------------------- |
|
28 |
|
29 EthiopicCalendar::EthiopicCalendar(const Locale& aLocale, |
|
30 UErrorCode& success, |
|
31 EEraType type /*= AMETE_MIHRET_ERA*/) |
|
32 : CECalendar(aLocale, success), |
|
33 eraType(type) |
|
34 { |
|
35 } |
|
36 |
|
37 EthiopicCalendar::EthiopicCalendar(const EthiopicCalendar& other) |
|
38 : CECalendar(other), |
|
39 eraType(other.eraType) |
|
40 { |
|
41 } |
|
42 |
|
43 EthiopicCalendar::~EthiopicCalendar() |
|
44 { |
|
45 } |
|
46 |
|
47 Calendar* |
|
48 EthiopicCalendar::clone() const |
|
49 { |
|
50 return new EthiopicCalendar(*this); |
|
51 } |
|
52 |
|
53 const char * |
|
54 EthiopicCalendar::getType() const |
|
55 { |
|
56 if (isAmeteAlemEra()) { |
|
57 return "ethiopic-amete-alem"; |
|
58 } |
|
59 return "ethiopic"; |
|
60 } |
|
61 |
|
62 void |
|
63 EthiopicCalendar::setAmeteAlemEra(UBool onOff) |
|
64 { |
|
65 eraType = onOff ? AMETE_ALEM_ERA : AMETE_MIHRET_ERA; |
|
66 } |
|
67 |
|
68 UBool |
|
69 EthiopicCalendar::isAmeteAlemEra() const |
|
70 { |
|
71 return (eraType == AMETE_ALEM_ERA); |
|
72 } |
|
73 |
|
74 //------------------------------------------------------------------------- |
|
75 // Calendar framework |
|
76 //------------------------------------------------------------------------- |
|
77 |
|
78 int32_t |
|
79 EthiopicCalendar::handleGetExtendedYear() |
|
80 { |
|
81 // Ethiopic calendar uses EXTENDED_YEAR aligned to |
|
82 // Amelete Hihret year always. |
|
83 int32_t eyear; |
|
84 if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) { |
|
85 eyear = internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1 |
|
86 } else if (isAmeteAlemEra()) { |
|
87 eyear = internalGet(UCAL_YEAR, 1 + AMETE_MIHRET_DELTA) |
|
88 - AMETE_MIHRET_DELTA; // Default to year 1 of Amelete Mihret |
|
89 } else { |
|
90 // The year defaults to the epoch start, the era to AMETE_MIHRET |
|
91 int32_t era = internalGet(UCAL_ERA, AMETE_MIHRET); |
|
92 if (era == AMETE_MIHRET) { |
|
93 eyear = internalGet(UCAL_YEAR, 1); // Default to year 1 |
|
94 } else { |
|
95 eyear = internalGet(UCAL_YEAR, 1) - AMETE_MIHRET_DELTA; |
|
96 } |
|
97 } |
|
98 return eyear; |
|
99 } |
|
100 |
|
101 void |
|
102 EthiopicCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/) |
|
103 { |
|
104 int32_t eyear, month, day, era, year; |
|
105 jdToCE(julianDay, getJDEpochOffset(), eyear, month, day); |
|
106 |
|
107 if (isAmeteAlemEra()) { |
|
108 era = AMETE_ALEM; |
|
109 year = eyear + AMETE_MIHRET_DELTA; |
|
110 } else { |
|
111 if (eyear > 0) { |
|
112 era = AMETE_MIHRET; |
|
113 year = eyear; |
|
114 } else { |
|
115 era = AMETE_ALEM; |
|
116 year = eyear + AMETE_MIHRET_DELTA; |
|
117 } |
|
118 } |
|
119 |
|
120 internalSet(UCAL_EXTENDED_YEAR, eyear); |
|
121 internalSet(UCAL_ERA, era); |
|
122 internalSet(UCAL_YEAR, year); |
|
123 internalSet(UCAL_MONTH, month); |
|
124 internalSet(UCAL_DATE, day); |
|
125 internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day); |
|
126 } |
|
127 |
|
128 int32_t |
|
129 EthiopicCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const |
|
130 { |
|
131 if (isAmeteAlemEra() && field == UCAL_ERA) { |
|
132 return 0; // Only one era in this mode, era is always 0 |
|
133 } |
|
134 return CECalendar::handleGetLimit(field, limitType); |
|
135 } |
|
136 |
|
137 /** |
|
138 * The system maintains a static default century start date and Year. They are |
|
139 * initialized the first time they are used. Once the system default century date |
|
140 * and year are set, they do not change. |
|
141 */ |
|
142 static UDate gSystemDefaultCenturyStart = DBL_MIN; |
|
143 static int32_t gSystemDefaultCenturyStartYear = -1; |
|
144 static icu::UInitOnce gSystemDefaultCenturyInit = U_INITONCE_INITIALIZER; |
|
145 |
|
146 static void U_CALLCONV initializeSystemDefaultCentury() |
|
147 { |
|
148 UErrorCode status = U_ZERO_ERROR; |
|
149 EthiopicCalendar calendar(Locale("@calendar=ethiopic"), status); |
|
150 if (U_SUCCESS(status)) { |
|
151 calendar.setTime(Calendar::getNow(), status); |
|
152 calendar.add(UCAL_YEAR, -80, status); |
|
153 |
|
154 gSystemDefaultCenturyStart = calendar.getTime(status); |
|
155 gSystemDefaultCenturyStartYear = calendar.get(UCAL_YEAR, status); |
|
156 } |
|
157 // We have no recourse upon failure unless we want to propagate the failure |
|
158 // out. |
|
159 } |
|
160 |
|
161 UDate |
|
162 EthiopicCalendar::defaultCenturyStart() const |
|
163 { |
|
164 // lazy-evaluate systemDefaultCenturyStart |
|
165 umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); |
|
166 return gSystemDefaultCenturyStart; |
|
167 } |
|
168 |
|
169 int32_t |
|
170 EthiopicCalendar::defaultCenturyStartYear() const |
|
171 { |
|
172 // lazy-evaluate systemDefaultCenturyStartYear |
|
173 umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); |
|
174 if (isAmeteAlemEra()) { |
|
175 return gSystemDefaultCenturyStartYear + AMETE_MIHRET_DELTA; |
|
176 } |
|
177 return gSystemDefaultCenturyStartYear; |
|
178 } |
|
179 |
|
180 |
|
181 int32_t |
|
182 EthiopicCalendar::getJDEpochOffset() const |
|
183 { |
|
184 return JD_EPOCH_OFFSET_AMETE_MIHRET; |
|
185 } |
|
186 |
|
187 |
|
188 #if 0 |
|
189 // We do not want to introduce this API in ICU4C. |
|
190 // It was accidentally introduced in ICU4J as a public API. |
|
191 |
|
192 //------------------------------------------------------------------------- |
|
193 // Calendar system Conversion methods... |
|
194 //------------------------------------------------------------------------- |
|
195 |
|
196 int32_t |
|
197 EthiopicCalendar::ethiopicToJD(int32_t year, int32_t month, int32_t date) |
|
198 { |
|
199 return ceToJD(year, month, date, JD_EPOCH_OFFSET_AMETE_MIHRET); |
|
200 } |
|
201 #endif |
|
202 |
|
203 U_NAMESPACE_END |
|
204 |
|
205 #endif |