]> git.saurik.com Git - apple/icu.git/blame_incremental - icuSources/i18n/buddhcal.cpp
ICU-3.13.tar.gz
[apple/icu.git] / icuSources / i18n / buddhcal.cpp
... / ...
CommitLineData
1/*
2*******************************************************************************
3* Copyright (C) 2003, 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
23U_NAMESPACE_BEGIN
24
25const char BuddhistCalendar::fgClassID = 0; // Value is irrelevant
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;
95 int32_t year = internalGet(UCAL_YEAR);
96 // ignore era
97 return GregorianCalendar::monthLength(month, getGregorianYear(status));
98}
99
100int32_t BuddhistCalendar::internalGetEra() const
101{
102 return isSet(UCAL_ERA) ? internalGet(UCAL_ERA) : BE;
103}
104
105int32_t
106BuddhistCalendar::getGregorianYear(UErrorCode &status) const
107{
108 int32_t year = (fStamp[UCAL_YEAR] != kUnset) ? internalGet(UCAL_YEAR) : kGregorianEpoch+kBuddhistEraStart;
109 int32_t era = BE;
110 if (fStamp[UCAL_ERA] != kUnset) {
111 era = internalGet(UCAL_ERA);
112 if (era != BE) {
113 status = U_ILLEGAL_ARGUMENT_ERROR;
114 return kGregorianEpoch + kBuddhistEraStart;
115 }
116 }
117 return year + kBuddhistEraStart;
118}
119
120void BuddhistCalendar::timeToFields(UDate theTime, UBool quick, UErrorCode& status)
121{
122 GregorianCalendar::timeToFields(theTime, quick, status);
123
124 int32_t era = internalGet(UCAL_ERA);
125 int32_t year = internalGet(UCAL_YEAR);
126
127 if(era == GregorianCalendar::BC) {
128 year = 1-year;
129 era = BuddhistCalendar::BE;
130 } else if(era == GregorianCalendar::AD) {
131 era = BuddhistCalendar::BE;
132 } else {
133 status = U_INTERNAL_PROGRAM_ERROR;
134 }
135
136 year = year - kBuddhistEraStart;
137
138 internalSet(UCAL_ERA, era);
139 internalSet(UCAL_YEAR, year);
140}
141
142void BuddhistCalendar::add(UCalendarDateFields field, int32_t amount, UErrorCode& status)
143{
144 if (U_FAILURE(status))
145 return;
146
147 if (amount == 0)
148 return; // Do nothing!
149
150 if(field == UCAL_YEAR /* || field == UCAL_YEAR_WOY */) {
151 int32_t year = internalGet(field);
152 int32_t era = internalGetEra();
153
154 year += amount;
155
156 set(field,year);
157 pinDayOfMonth();
158 } else {
159 GregorianCalendar::add(field,amount,status);
160 }
161}
162
163
164
165// default century
166const UDate BuddhistCalendar::fgSystemDefaultCentury = DBL_MIN;
167const int32_t BuddhistCalendar::fgSystemDefaultCenturyYear = -1;
168
169UDate BuddhistCalendar::fgSystemDefaultCenturyStart = DBL_MIN;
170int32_t BuddhistCalendar::fgSystemDefaultCenturyStartYear = -1;
171
172
173UBool BuddhistCalendar::haveDefaultCentury() const
174{
175 return TRUE;
176}
177
178UDate BuddhistCalendar::defaultCenturyStart() const
179{
180 return internalGetDefaultCenturyStart();
181}
182
183int32_t BuddhistCalendar::defaultCenturyStartYear() const
184{
185 return internalGetDefaultCenturyStartYear();
186}
187
188UDate
189BuddhistCalendar::internalGetDefaultCenturyStart() const
190{
191 // lazy-evaluate systemDefaultCenturyStart
192 UBool needsUpdate;
193 {
194 Mutex m;
195 needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
196 }
197
198 if (needsUpdate) {
199 initializeSystemDefaultCentury();
200 }
201
202 // use defaultCenturyStart unless it's the flag value;
203 // then use systemDefaultCenturyStart
204
205 return fgSystemDefaultCenturyStart;
206}
207
208int32_t
209BuddhistCalendar::internalGetDefaultCenturyStartYear() const
210{
211 // lazy-evaluate systemDefaultCenturyStartYear
212 UBool needsUpdate;
213 {
214 Mutex m;
215 needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
216 }
217
218 if (needsUpdate) {
219 initializeSystemDefaultCentury();
220 }
221
222 // use defaultCenturyStart unless it's the flag value;
223 // then use systemDefaultCenturyStartYear
224
225 return fgSystemDefaultCenturyStartYear;
226}
227
228void
229BuddhistCalendar::initializeSystemDefaultCentury()
230{
231 // initialize systemDefaultCentury and systemDefaultCenturyYear based
232 // on the current time. They'll be set to 80 years before
233 // the current time.
234 // No point in locking as it should be idempotent.
235 if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury)
236 {
237 UErrorCode status = U_ZERO_ERROR;
238 Calendar *calendar = new BuddhistCalendar(Locale("th_TH_TRADITIONAL"),status);
239 if (calendar != NULL && U_SUCCESS(status))
240 {
241 calendar->setTime(Calendar::getNow(), status);
242 calendar->add(UCAL_YEAR, -80, status);
243 UDate newStart = calendar->getTime(status);
244 int32_t newYear = calendar->get(UCAL_YEAR, status);
245 {
246 Mutex m;
247 fgSystemDefaultCenturyStart = newStart;
248 fgSystemDefaultCenturyStartYear = newYear;
249 }
250 delete calendar;
251 }
252 // We have no recourse upon failure unless we want to propagate the failure
253 // out.
254 }
255}
256
257
258U_NAMESPACE_END
259
260#endif