]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/buddhcal.cpp
ICU-8.11.4.tar.gz
[apple/icu.git] / icuSources / i18n / buddhcal.cpp
CommitLineData
b75a7d8f
A
1/*
2*******************************************************************************
374ca955 3* Copyright (C) 2003-2004, International Business Machines Corporation and *
b75a7d8f
A
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
23U_NAMESPACE_BEGIN
24
374ca955 25UOBJECT_DEFINE_RTTI_IMPLEMENTATION(BuddhistCalendar)
b75a7d8f
A
26
27static const int32_t kMaxEra = 0; // only 1 era
28
29static const int32_t kBuddhistEraStart = -543; // 544 BC (Gregorian)
30
31static const int32_t kGregorianEpoch = 1970;
32
33BuddhistCalendar::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
39BuddhistCalendar::~BuddhistCalendar()
40{
41}
42
43BuddhistCalendar::BuddhistCalendar(const BuddhistCalendar& source)
44 : GregorianCalendar(source)
45{
46}
47
48BuddhistCalendar& BuddhistCalendar::operator= ( const BuddhistCalendar& right)
49{
50 GregorianCalendar::operator=(right);
51 return *this;
52}
53
54Calendar* BuddhistCalendar::clone(void) const
55{
56 return new BuddhistCalendar(*this);
57}
58
59const char *BuddhistCalendar::getType() const
60{
61 return "buddhist";
62}
63
64int32_t
65BuddhistCalendar::getMaximum(UCalendarDateFields field) const
66{
67 if(field == UCAL_ERA) {
68 return kMaxEra;
69 } else {
70 return GregorianCalendar::getMaximum(field);
71 }
72}
73
74int32_t
75BuddhistCalendar::getLeastMaximum(UCalendarDateFields field) const
76{
77 if(field == UCAL_ERA) {
78 return kMaxEra;
79 } else {
80 return GregorianCalendar::getLeastMaximum(field);
81 }
82}
83
84int32_t
85BuddhistCalendar::monthLength(int32_t month, int32_t year) const
86{
87 return GregorianCalendar::monthLength(month,year);
88}
89
90
91int32_t
92BuddhistCalendar::monthLength(int32_t month) const
93{
94 UErrorCode status = U_ZERO_ERROR;
b75a7d8f
A
95 // ignore era
96 return GregorianCalendar::monthLength(month, getGregorianYear(status));
97}
98
99int32_t BuddhistCalendar::internalGetEra() const
100{
374ca955 101 return internalGet(UCAL_ERA, BE);
b75a7d8f
A
102}
103
104int32_t
105BuddhistCalendar::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
374ca955
A
119int32_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
131int32_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
138void 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
147int32_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
b75a7d8f
A
157void BuddhistCalendar::timeToFields(UDate theTime, UBool quick, UErrorCode& status)
158{
374ca955 159 //Calendar::timeToFields(theTime, quick, status);
b75a7d8f
A
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}
374ca955 178#endif
b75a7d8f
A
179
180void 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 */) {
374ca955 189 int32_t year = get(field, status); // not internalGet -- force completion
b75a7d8f
A
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
203const UDate BuddhistCalendar::fgSystemDefaultCentury = DBL_MIN;
204const int32_t BuddhistCalendar::fgSystemDefaultCenturyYear = -1;
205
206UDate BuddhistCalendar::fgSystemDefaultCenturyStart = DBL_MIN;
207int32_t BuddhistCalendar::fgSystemDefaultCenturyStartYear = -1;
208
209
210UBool BuddhistCalendar::haveDefaultCentury() const
211{
212 return TRUE;
213}
214
215UDate BuddhistCalendar::defaultCenturyStart() const
216{
217 return internalGetDefaultCenturyStart();
218}
219
220int32_t BuddhistCalendar::defaultCenturyStartYear() const
221{
222 return internalGetDefaultCenturyStartYear();
223}
224
225UDate
226BuddhistCalendar::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
245int32_t
246BuddhistCalendar::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
265void
266BuddhistCalendar::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;
374ca955
A
275 BuddhistCalendar calendar(Locale("@calendar=buddhist"),status);
276 if (U_SUCCESS(status))
b75a7d8f 277 {
374ca955
A
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);
b75a7d8f
A
282 {
283 Mutex m;
284 fgSystemDefaultCenturyStart = newStart;
285 fgSystemDefaultCenturyStartYear = newYear;
286 }
b75a7d8f
A
287 }
288 // We have no recourse upon failure unless we want to propagate the failure
289 // out.
290 }
291}
292
293
294U_NAMESPACE_END
295
296#endif