2 * Copyright (c) 2010, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
6 * Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
7 * Oliver Tappe <zooey@hirschkaefer.de>
11 #include <unicode/uversion.h>
16 #include <unicode/locid.h>
17 #include <unicode/timezone.h>
18 #include <ICUWrapper.h>
23 const char* BTimeZone::kNameOfGmtZone
= "GMT";
26 static const BString skEmptyString
;
29 static const uint32 skNameField
= 1U << 0;
30 static const uint32 skDaylightSavingNameField
= 1U << 1;
31 static const uint32 skShortNameField
= 1U << 2;
32 static const uint32 skShortDaylightSavingNameField
= 1U << 3;
33 static const uint32 skLongGenericNameField
= 1U << 4;
34 static const uint32 skGenericLocationNameField
= 1U << 5;
35 static const uint32 skShortCommonlyUsedNameField
= 1U << 6;
36 static const uint32 skSupportsDaylightSavingField
= 1U << 7;
37 static const uint32 skOffsetFromGMTField
= 1U << 8;
40 BTimeZone::BTimeZone(const char* zoneID
, const BLanguage
* language
)
44 fInitStatus(B_NO_INIT
),
47 SetTo(zoneID
, language
);
51 BTimeZone::BTimeZone(const BTimeZone
& other
)
53 fICUTimeZone(other
.fICUTimeZone
== NULL
55 : other
.fICUTimeZone
->clone()),
56 fICULocale(other
.fICULocale
== NULL
58 : other
.fICULocale
->clone()),
59 fInitStatus(other
.fInitStatus
),
60 fInitializedFields(other
.fInitializedFields
),
61 fZoneID(other
.fZoneID
),
63 fDaylightSavingName(other
.fDaylightSavingName
),
64 fShortName(other
.fShortName
),
65 fShortDaylightSavingName(other
.fShortDaylightSavingName
),
66 fOffsetFromGMT(other
.fOffsetFromGMT
),
67 fSupportsDaylightSaving(other
.fSupportsDaylightSaving
)
72 BTimeZone::~BTimeZone()
79 BTimeZone
& BTimeZone::operator=(const BTimeZone
& source
)
82 fICUTimeZone
= source
.fICUTimeZone
== NULL
84 : source
.fICUTimeZone
->clone();
85 fICULocale
= source
.fICULocale
== NULL
87 : source
.fICULocale
->clone();
88 fInitStatus
= source
.fInitStatus
;
89 fInitializedFields
= source
.fInitializedFields
;
90 fZoneID
= source
.fZoneID
;
92 fDaylightSavingName
= source
.fDaylightSavingName
;
93 fShortName
= source
.fShortName
;
94 fShortDaylightSavingName
= source
.fShortDaylightSavingName
;
95 fOffsetFromGMT
= source
.fOffsetFromGMT
;
96 fSupportsDaylightSaving
= source
.fSupportsDaylightSaving
;
103 BTimeZone::ID() const
110 BTimeZone::Name() const
112 if ((fInitializedFields
& skNameField
) == 0) {
113 UnicodeString unicodeString
;
114 if (fICULocale
!= NULL
) {
115 fICUTimeZone
->getDisplayName(false, TimeZone::GENERIC_LOCATION
,
116 *fICULocale
, unicodeString
);
118 fICUTimeZone
->getDisplayName(false, TimeZone::GENERIC_LOCATION
,
121 BStringByteSink
sink(&fName
);
122 unicodeString
.toUTF8(sink
);
123 fInitializedFields
|= skNameField
;
131 BTimeZone::DaylightSavingName() const
133 if ((fInitializedFields
& skDaylightSavingNameField
) == 0) {
134 UnicodeString unicodeString
;
135 if (fICULocale
!= NULL
) {
136 fICUTimeZone
->getDisplayName(true, TimeZone::GENERIC_LOCATION
,
137 *fICULocale
, unicodeString
);
139 fICUTimeZone
->getDisplayName(true, TimeZone::GENERIC_LOCATION
,
142 BStringByteSink
sink(&fDaylightSavingName
);
143 unicodeString
.toUTF8(sink
);
144 fInitializedFields
|= skDaylightSavingNameField
;
147 return fDaylightSavingName
;
152 BTimeZone::ShortName() const
154 if ((fInitializedFields
& skShortNameField
) == 0) {
155 UnicodeString unicodeString
;
156 if (fICULocale
!= NULL
) {
157 fICUTimeZone
->getDisplayName(false, TimeZone::SHORT
, *fICULocale
,
160 fICUTimeZone
->getDisplayName(false, TimeZone::SHORT
, unicodeString
);
162 BStringByteSink
sink(&fShortName
);
163 unicodeString
.toUTF8(sink
);
164 fInitializedFields
|= skShortNameField
;
172 BTimeZone::ShortDaylightSavingName() const
174 if ((fInitializedFields
& skShortDaylightSavingNameField
) == 0) {
175 UnicodeString unicodeString
;
176 if (fICULocale
!= NULL
) {
177 fICUTimeZone
->getDisplayName(true, TimeZone::SHORT
, *fICULocale
,
180 fICUTimeZone
->getDisplayName(true, TimeZone::SHORT
, unicodeString
);
182 BStringByteSink
sink(&fShortDaylightSavingName
);
183 unicodeString
.toUTF8(sink
);
184 fInitializedFields
|= skShortDaylightSavingNameField
;
187 return fShortDaylightSavingName
;
192 BTimeZone::OffsetFromGMT() const
194 if ((fInitializedFields
& skOffsetFromGMTField
) == 0) {
197 UDate nowMillis
= 1000 * (double)time(NULL
);
199 UErrorCode error
= U_ZERO_ERROR
;
200 fICUTimeZone
->getOffset(nowMillis
, FALSE
, rawOffset
, dstOffset
, error
);
201 if (!U_SUCCESS(error
))
204 fOffsetFromGMT
= (rawOffset
+ dstOffset
) / 1000;
205 // we want seconds, not ms (which ICU gives us)
207 fInitializedFields
|= skOffsetFromGMTField
;
210 return fOffsetFromGMT
;
215 BTimeZone::SupportsDaylightSaving() const
217 if ((fInitializedFields
& skSupportsDaylightSavingField
) == 0) {
218 fSupportsDaylightSaving
= fICUTimeZone
->useDaylightTime();
219 fInitializedFields
|= skSupportsDaylightSavingField
;
222 return fSupportsDaylightSaving
;
227 BTimeZone::InitCheck() const
234 BTimeZone::SetLanguage(const BLanguage
* language
)
236 return SetTo(fZoneID
, language
);
241 BTimeZone::SetTo(const char* zoneID
, const BLanguage
* language
)
246 fInitializedFields
= 0;
248 if (zoneID
== NULL
|| zoneID
[0] == '\0')
249 fICUTimeZone
= TimeZone::createDefault();
251 fICUTimeZone
= TimeZone::createTimeZone(zoneID
);
253 if (fICUTimeZone
== NULL
) {
254 fInitStatus
= B_NAME_NOT_FOUND
;
258 if (language
!= NULL
) {
259 fICULocale
= new Locale(language
->Code());
260 if (fICULocale
== NULL
) {
261 fInitStatus
= B_NO_MEMORY
;
266 UnicodeString unicodeString
;
267 fICUTimeZone
->getID(unicodeString
);
268 BStringByteSink
sink(&fZoneID
);
269 unicodeString
.toUTF8(sink
);