]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/buddhcal.cpp
ICU-8.11.tar.gz
[apple/icu.git] / icuSources / i18n / buddhcal.cpp
1 /*
2 *******************************************************************************
3 * Copyright (C) 2003-2004, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
6 *
7 * File BUDDHCAL.CPP
8 *
9 * Modification History:
10 * 05/13/2003 srl copied from gregocal.cpp
11 *
12 */
13
14 #include "unicode/utypes.h"
15
16 #if !UCONFIG_NO_FORMATTING
17
18 #include "buddhcal.h"
19 #include "unicode/gregocal.h"
20 #include "mutex.h"
21 #include <float.h>
22
23 U_NAMESPACE_BEGIN
24
25 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(BuddhistCalendar)
26
27 static const int32_t kMaxEra = 0; // only 1 era
28
29 static const int32_t kBuddhistEraStart = -543; // 544 BC (Gregorian)
30
31 static const int32_t kGregorianEpoch = 1970;
32
33 BuddhistCalendar::BuddhistCalendar(const Locale& aLocale, UErrorCode& success)
34 : GregorianCalendar(aLocale, success)
35 {
36 setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly.
37 }
38
39 BuddhistCalendar::~BuddhistCalendar()
40 {
41 }
42
43 BuddhistCalendar::BuddhistCalendar(const BuddhistCalendar& source)
44 : GregorianCalendar(source)
45 {
46 }
47
48 BuddhistCalendar& BuddhistCalendar::operator= ( const BuddhistCalendar& right)
49 {
50 GregorianCalendar::operator=(right);
51 return *this;
52 }
53
54 Calendar* BuddhistCalendar::clone(void) const
55 {
56 return new BuddhistCalendar(*this);
57 }
58
59 const char *BuddhistCalendar::getType() const
60 {
61 return "buddhist";
62 }
63
64 int32_t
65 BuddhistCalendar::getMaximum(UCalendarDateFields field) const
66 {
67 if(field == UCAL_ERA) {
68 return kMaxEra;
69 } else {
70 return GregorianCalendar::getMaximum(field);
71 }
72 }
73
74 int32_t
75 BuddhistCalendar::getLeastMaximum(UCalendarDateFields field) const
76 {
77 if(field == UCAL_ERA) {
78 return kMaxEra;
79 } else {
80 return GregorianCalendar::getLeastMaximum(field);
81 }
82 }
83
84 int32_t
85 BuddhistCalendar::monthLength(int32_t month, int32_t year) const
86 {
87 return GregorianCalendar::monthLength(month,year);
88 }
89
90
91 int32_t
92 BuddhistCalendar::monthLength(int32_t month) const
93 {
94 UErrorCode status = U_ZERO_ERROR;
95 // ignore era
96 return GregorianCalendar::monthLength(month, getGregorianYear(status));
97 }
98
99 int32_t BuddhistCalendar::internalGetEra() const
100 {
101 return internalGet(UCAL_ERA, BE);
102 }
103
104 int32_t
105 BuddhistCalendar::getGregorianYear(UErrorCode &status) const
106 {
107 int32_t year = (fStamp[UCAL_YEAR] != kUnset) ? internalGet(UCAL_YEAR) : kGregorianEpoch+kBuddhistEraStart;
108 int32_t era = BE;
109 if (fStamp[UCAL_ERA] != kUnset) {
110 era = internalGet(UCAL_ERA);
111 if (era != BE) {
112 status = U_ILLEGAL_ARGUMENT_ERROR;
113 return kGregorianEpoch + kBuddhistEraStart;
114 }
115 }
116 return year + kBuddhistEraStart;
117 }
118
119 int32_t BuddhistCalendar::handleGetExtendedYear()
120 {
121 int32_t year;
122 if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
123 year = internalGet(UCAL_EXTENDED_YEAR, 1);
124 } else {
125 // Ignore the era, as there is only one
126 year = internalGet(UCAL_YEAR, 1);
127 }
128 return year;
129 }
130
131 int32_t BuddhistCalendar::handleComputeMonthStart(int32_t eyear, int32_t month,
132
133 UBool useMonth) const
134 {
135 return GregorianCalendar::handleComputeMonthStart(eyear+kBuddhistEraStart, month, useMonth);
136 }
137
138 void BuddhistCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
139 {
140 GregorianCalendar::handleComputeFields(julianDay, status);
141 int32_t y = internalGet(UCAL_EXTENDED_YEAR) - kBuddhistEraStart;
142 internalSet(UCAL_EXTENDED_YEAR, y);
143 internalSet(UCAL_ERA, 0);
144 internalSet(UCAL_YEAR, y);
145 }
146
147 int32_t BuddhistCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const
148 {
149 if(field == UCAL_ERA) {
150 return BE;
151 } else {
152 return GregorianCalendar::handleGetLimit(field,limitType);
153 }
154 }
155
156 #if 0
157 void BuddhistCalendar::timeToFields(UDate theTime, UBool quick, UErrorCode& status)
158 {
159 //Calendar::timeToFields(theTime, quick, status);
160
161 int32_t era = internalGet(UCAL_ERA);
162 int32_t year = internalGet(UCAL_YEAR);
163
164 if(era == GregorianCalendar::BC) {
165 year = 1-year;
166 era = BuddhistCalendar::BE;
167 } else if(era == GregorianCalendar::AD) {
168 era = BuddhistCalendar::BE;
169 } else {
170 status = U_INTERNAL_PROGRAM_ERROR;
171 }
172
173 year = year - kBuddhistEraStart;
174
175 internalSet(UCAL_ERA, era);
176 internalSet(UCAL_YEAR, year);
177 }
178 #endif
179
180 void BuddhistCalendar::add(UCalendarDateFields field, int32_t amount, UErrorCode& status)
181 {
182 if (U_FAILURE(status))
183 return;
184
185 if (amount == 0)
186 return; // Do nothing!
187
188 if(field == UCAL_YEAR /* || field == UCAL_YEAR_WOY */) {
189 int32_t year = get(field, status); // not internalGet -- force completion
190
191 year += amount;
192
193 set(field,year);
194 pinDayOfMonth();
195 } else {
196 GregorianCalendar::add(field,amount,status);
197 }
198 }
199
200
201
202 // default century
203 const UDate BuddhistCalendar::fgSystemDefaultCentury = DBL_MIN;
204 const int32_t BuddhistCalendar::fgSystemDefaultCenturyYear = -1;
205
206 UDate BuddhistCalendar::fgSystemDefaultCenturyStart = DBL_MIN;
207 int32_t BuddhistCalendar::fgSystemDefaultCenturyStartYear = -1;
208
209
210 UBool BuddhistCalendar::haveDefaultCentury() const
211 {
212 return TRUE;
213 }
214
215 UDate BuddhistCalendar::defaultCenturyStart() const
216 {
217 return internalGetDefaultCenturyStart();
218 }
219
220 int32_t BuddhistCalendar::defaultCenturyStartYear() const
221 {
222 return internalGetDefaultCenturyStartYear();
223 }
224
225 UDate
226 BuddhistCalendar::internalGetDefaultCenturyStart() const
227 {
228 // lazy-evaluate systemDefaultCenturyStart
229 UBool needsUpdate;
230 {
231 Mutex m;
232 needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
233 }
234
235 if (needsUpdate) {
236 initializeSystemDefaultCentury();
237 }
238
239 // use defaultCenturyStart unless it's the flag value;
240 // then use systemDefaultCenturyStart
241
242 return fgSystemDefaultCenturyStart;
243 }
244
245 int32_t
246 BuddhistCalendar::internalGetDefaultCenturyStartYear() const
247 {
248 // lazy-evaluate systemDefaultCenturyStartYear
249 UBool needsUpdate;
250 {
251 Mutex m;
252 needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
253 }
254
255 if (needsUpdate) {
256 initializeSystemDefaultCentury();
257 }
258
259 // use defaultCenturyStart unless it's the flag value;
260 // then use systemDefaultCenturyStartYear
261
262 return fgSystemDefaultCenturyStartYear;
263 }
264
265 void
266 BuddhistCalendar::initializeSystemDefaultCentury()
267 {
268 // initialize systemDefaultCentury and systemDefaultCenturyYear based
269 // on the current time. They'll be set to 80 years before
270 // the current time.
271 // No point in locking as it should be idempotent.
272 if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury)
273 {
274 UErrorCode status = U_ZERO_ERROR;
275 BuddhistCalendar calendar(Locale("@calendar=buddhist"),status);
276 if (U_SUCCESS(status))
277 {
278 calendar.setTime(Calendar::getNow(), status);
279 calendar.add(UCAL_YEAR, -80, status);
280 UDate newStart = calendar.getTime(status);
281 int32_t newYear = calendar.get(UCAL_YEAR, status);
282 {
283 Mutex m;
284 fgSystemDefaultCenturyStart = newStart;
285 fgSystemDefaultCenturyStartYear = newYear;
286 }
287 }
288 // We have no recourse upon failure unless we want to propagate the failure
289 // out.
290 }
291 }
292
293
294 U_NAMESPACE_END
295
296 #endif