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