2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FLcl_TimeZoneImpl.cpp
20 * @brief This is the implementation file for _TimeZoneImpl class.
23 #include <unique_ptr.h>
25 #include <FBaseSysLog.h>
26 #include <FLclTimeZone.h>
28 #include "FLcl_LocaleData.h"
29 #include "FLcl_TimeZoneImpl.h"
31 using namespace Tizen::Base;
33 namespace Tizen { namespace Locales
36 _TimeZoneImpl::_TimeZoneImpl(void)
37 : __icuTimeZone(0, "")
38 , __dstStartingYear(0)
39 , __startingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
40 , __endingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
45 _TimeZoneImpl::_TimeZoneImpl(int rawOffset, const String& id)
46 : __icuTimeZone(rawOffset * ONE_MIN_IN_MILLISEC, _LocaleData::GetIcuString(id))
47 , __dstStartingYear(0)
48 , __startingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
49 , __endingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
54 _TimeZoneImpl::_TimeZoneImpl(int rawOffset, const String& id, const TimeRule& startRule, const TimeRule& endRule, int dstOffset)
55 : __icuTimeZone(rawOffset * ONE_MIN_IN_MILLISEC, _LocaleData::GetIcuString(id))
56 , __dstStartingYear(0)
57 , __startingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
58 , __endingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
60 SetDstRules(startRule, endRule, dstOffset);
63 _TimeZoneImpl::_TimeZoneImpl(const _TimeZoneImpl& otherTimeZone)
64 : __icuTimeZone(otherTimeZone.__icuTimeZone)
65 , __dstStartingYear(otherTimeZone.__dstStartingYear)
66 , __startingRule(otherTimeZone.__startingRule)
67 , __endingRule(otherTimeZone.__endingRule)
71 _TimeZoneImpl::_TimeZoneImpl(U_ICU_NAMESPACE::TimeZone& icuTimeZone)
72 : __icuTimeZone(0, "")
73 , __dstStartingYear(0)
74 , __startingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
75 , __endingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
77 U_ICU_NAMESPACE::UnicodeString id;
78 __icuTimeZone.setID(icuTimeZone.getID(id));
79 __icuTimeZone.setRawOffset(icuTimeZone.getRawOffset());
82 _TimeZoneImpl::_TimeZoneImpl(U_ICU_NAMESPACE::TimeZone& icuTimeZone, UDate icuDate)
83 : __icuTimeZone(0, "")
84 , __dstStartingYear(0)
85 , __startingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
86 , __endingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
88 U_ICU_NAMESPACE::UnicodeString id;
89 __icuTimeZone.setID(icuTimeZone.getID(id));
90 __icuTimeZone.setRawOffset(icuTimeZone.getRawOffset());
92 U_ICU_NAMESPACE::BasicTimeZone* pIcuTz = dynamic_cast<U_ICU_NAMESPACE::BasicTimeZone*>(&icuTimeZone);
95 TimeRule startingRule(MONTH_UNDEFINED, DAY_UNDEFINED);
96 TimeRule endingRule(MONTH_UNDEFINED, DAY_UNDEFINED);
99 UErrorCode status = U_ZERO_ERROR;
100 U_ICU_NAMESPACE::InitialTimeZoneRule* pInitial = null;
101 U_ICU_NAMESPACE::AnnualTimeZoneRule* pStd = null;
102 U_ICU_NAMESPACE::AnnualTimeZoneRule* pDst = null;
103 pIcuTz->getSimpleRulesNear(icuDate, pInitial, pStd, pDst, status);
106 result r = GetTimeRuleFromIcuDateTimeRule(pDst->getRule(), startingRule);
109 dstSaving = pIcuTz->getDSTSavings() / ONE_MIN_IN_MILLISEC;
110 GetTimeRuleFromIcuDateTimeRule(pStd->getRule(), endingRule);
113 int dstStartingYear = pDst->getStartYear();
114 SetDstStartingYear(dstStartingYear);
120 SetDstRules(startingRule, endingRule, dstSaving);
125 _TimeZoneImpl::CloneN(void)
127 return new (std::nothrow) _TimeZoneImpl(*this);
131 _TimeZoneImpl::operator =(const _TimeZoneImpl& otherTimeZone)
133 if (*this != otherTimeZone)
135 __icuTimeZone = otherTimeZone.__icuTimeZone;
136 __dstStartingYear = otherTimeZone.__dstStartingYear;
137 __startingRule = otherTimeZone.__startingRule;
138 __endingRule = otherTimeZone.__endingRule;
143 _TimeZoneImpl::~_TimeZoneImpl(void)
148 U_ICU_NAMESPACE::SimpleTimeZone
149 _TimeZoneImpl::GetIcuTimeZone(void) const
151 return __icuTimeZone;
156 _TimeZoneImpl::operator ==(const _TimeZoneImpl& otherTimeZone) const
158 return __icuTimeZone == otherTimeZone.__icuTimeZone;
162 _TimeZoneImpl::operator !=(const _TimeZoneImpl& otherTimeZone) const
164 return !(*this == otherTimeZone);
168 _TimeZoneImpl::Equals(const Object& obj) const
170 const _TimeZoneImpl* pTimeZoneImpl = dynamic_cast<const _TimeZoneImpl*>(&obj);
173 return (*this == *pTimeZoneImpl);
179 _TimeZoneImpl::GetHashCode(void) const
181 int hashCode = GetId().GetHashCode();
182 Integer intValues = GetRawOffset() + GetDstSavings() + GetDstStartingYear() + IsDstUsed();
183 hashCode = (hashCode << 5) - hashCode + intValues.GetHashCode();
184 hashCode = (hashCode << 5) - hashCode + __startingRule.GetHashCode();
185 hashCode = (hashCode << 5) - hashCode + __endingRule.GetHashCode();
191 _TimeZoneImpl::GetId(void) const
193 U_ICU_NAMESPACE::UnicodeString icuStr;
194 return _LocaleData::GetOspString(__icuTimeZone.getID(icuStr));
198 _TimeZoneImpl::SetId(const String& id)
200 U_ICU_NAMESPACE::UnicodeString icuStr = _LocaleData::GetIcuString(id);
201 __icuTimeZone.setID(icuStr);
205 _TimeZoneImpl::GetRawOffset(void) const
207 return __icuTimeZone.getRawOffset() / ONE_MIN_IN_MILLISEC;
211 _TimeZoneImpl::SetRawOffset(int rawOffset)
213 __icuTimeZone.setRawOffset(rawOffset * ONE_MIN_IN_MILLISEC);
217 _TimeZoneImpl::GetDstStartingYear(void) const
219 return __dstStartingYear;
223 _TimeZoneImpl::SetDstStartingYear(int year)
225 __dstStartingYear = year;
226 __icuTimeZone.setStartYear(year);
230 _TimeZoneImpl::GetDstSavings(void) const
232 return __icuTimeZone.getDSTSavings() / ONE_MIN_IN_MILLISEC;
236 _TimeZoneImpl::SetDstSavings(int dstSavings)
238 UErrorCode ec = U_ZERO_ERROR;
239 __icuTimeZone.setDSTSavings(dstSavings * ONE_MIN_IN_MILLISEC, ec);
243 _TimeZoneImpl::GetDstStartingRule(void) const
245 return __startingRule.GetMonth() != MONTH_UNDEFINED ? &__startingRule : null;
249 _TimeZoneImpl::SetDstStartingRule(const TimeRule& startRule)
252 int dayOfWeekInMonth = 0;
257 UErrorCode ec = U_ZERO_ERROR;
258 GetIcuTimeRuleValue(startRule, month, dayOfWeekInMonth, dayOfWeek, time, mode);
260 U_ICU_NAMESPACE::SimpleTimeZone::TimeMode timeMode = static_cast<U_ICU_NAMESPACE::SimpleTimeZone::TimeMode> (mode);
261 __icuTimeZone.setStartRule(month, dayOfWeekInMonth, dayOfWeek, time, timeMode, ec);
262 __startingRule = startRule;
266 _TimeZoneImpl::GetDstEndingRule(void) const
268 return __endingRule.GetMonth() != MONTH_UNDEFINED ? &__endingRule : null;
272 _TimeZoneImpl::SetDstEndingRule(const TimeRule& endRule)
275 int dayOfWeekInMonth = 0;
280 UErrorCode ec = U_ZERO_ERROR;
281 GetIcuTimeRuleValue(endRule, month, dayOfWeekInMonth, dayOfWeek, time, mode);
283 U_ICU_NAMESPACE::SimpleTimeZone::TimeMode timeMode = static_cast<U_ICU_NAMESPACE::SimpleTimeZone::TimeMode> (mode);
284 __icuTimeZone.setEndRule(month, dayOfWeekInMonth, dayOfWeek, time, timeMode, ec);
285 __endingRule = endRule;
289 _TimeZoneImpl::SetDstRules(const TimeRule& startRule, const TimeRule& endRule, int dstSavings)
291 SysTryReturnResult(NID_LCL, dstSavings >= 0,
292 E_OUT_OF_RANGE, "dstSavings [%d] should be greater or equal to than 0", dstSavings);
293 SysTryReturnResult(NID_LCL, dstSavings < ONE_DAY_IN_MINUTE,
294 E_OUT_OF_RANGE, "dstSavings [%d] should be greater than %d", dstSavings, ONE_DAY_IN_MINUTE);
295 SetDstStartingRule(startRule);
296 SetDstEndingRule(endRule);
297 SetDstSavings(dstSavings);
302 _TimeZoneImpl::GetOffset(const DateTime& date, bool local, int& rawOffset, int& dstOffset) const
304 UErrorCode ec = U_ZERO_ERROR;
305 __icuTimeZone.getOffset(_LocaleData::GetIcuDate(date), local, rawOffset, dstOffset, ec);
306 rawOffset /= ONE_MIN_IN_MILLISEC;
307 dstOffset /= ONE_MIN_IN_MILLISEC;
308 return U_SUCCESS(ec) ? E_SUCCESS : E_INVALID_ARG;
312 _TimeZoneImpl::GetOffset(long long ticks, int& offset) const
316 date.SetValue(ts.GetTicks());
320 UErrorCode ec = U_ZERO_ERROR;
321 __icuTimeZone.getOffset(_LocaleData::GetIcuDate(date), false, rawOffset, dstOffset, ec);
322 offset = (rawOffset + dstOffset) / ONE_MIN_IN_MILLISEC;
323 return U_SUCCESS(ec) ? E_SUCCESS : E_INVALID_ARG;
327 _TimeZoneImpl::IsDstUsed(void) const
329 return __icuTimeZone.useDaylightTime();
333 _TimeZoneImpl::GetTimeZoneImpl(const TimeZone& ospTimeZone)
335 return ospTimeZone.__pTimeZoneImpl;
339 _TimeZoneImpl::GetTimeZone(const String& id, Tizen::Locales::TimeZone& timeZone)
341 U_ICU_NAMESPACE::UnicodeString icuStr = _LocaleData::GetIcuString(id);
342 std::unique_ptr<U_ICU_NAMESPACE::TimeZone> pIcuTimeZone(U_ICU_NAMESPACE::TimeZone::createTimeZone(icuStr));
343 SysTryReturnResult(NID_LCL, pIcuTimeZone != null, E_INVALID_ARG, "Unable to create ICU timezone");
345 U_ICU_NAMESPACE::UnicodeString retIcuStr;
346 SysTryReturnResult(NID_LCL, pIcuTimeZone->getID(retIcuStr) == icuStr,
347 E_INVALID_ARG, "Unsupported timezone id [%ls]", id.GetPointer());
349 U_ICU_NAMESPACE::SimpleTimeZone icuTimeZone(pIcuTimeZone->getRawOffset(), icuStr);
350 std::unique_ptr<_TimeZoneImpl> pTimeZoneImpl(new (std::nothrow) _TimeZoneImpl(icuTimeZone));
353 delete timeZone.__pTimeZoneImpl;
354 timeZone.__pTimeZoneImpl = pTimeZoneImpl.release();
358 return E_INVALID_ARG;
362 _TimeZoneImpl::GetTimeZone(const String& id, const DateTime& utcTime, Tizen::Locales::TimeZone& timeZone)
364 U_ICU_NAMESPACE::UnicodeString icuStr = _LocaleData::GetIcuString(id);
365 std::unique_ptr<U_ICU_NAMESPACE::TimeZone> pIcuTimeZone(U_ICU_NAMESPACE::TimeZone::createTimeZone(icuStr));
366 SysTryReturnResult(NID_LCL, pIcuTimeZone != null, E_INVALID_ARG, "Unable to create ICU timezone");
368 U_ICU_NAMESPACE::UnicodeString retIcuStr;
369 SysTryReturnResult(NID_LCL, pIcuTimeZone->getID(retIcuStr) == icuStr,
370 E_INVALID_ARG, "Unsupported timezone id [%ls]", id.GetPointer());
372 std::unique_ptr<_TimeZoneImpl> pTimeZoneImpl(new (std::nothrow) _TimeZoneImpl(*pIcuTimeZone, _LocaleData::GetIcuDate(utcTime)));
375 delete timeZone.__pTimeZoneImpl;
376 timeZone.__pTimeZoneImpl = pTimeZoneImpl.release();
380 return E_INVALID_ARG;
384 _TimeZoneImpl::GetIcuTimeRuleValue(const TimeRule& ospRule, int& month, int& dayOfWeekInMonth, int& dayOfWeek, int& time, int& mode)
386 if (ospRule.GetMonth() != MONTH_UNDEFINED)
388 month = ospRule.GetMonth() - 1;
390 int ospDay = ospRule.GetDay();
391 dayOfWeekInMonth = (ospDay == TimeRule::DAY_UNDEFINED)? 0 : ospDay;
393 int ospDayOfWeek = ospRule.GetDayOfWeek();
394 dayOfWeek = (ospDayOfWeek == WEEK_UNDEFINED)? 0 : ospDayOfWeek;
396 time = ospRule.GetHour() * ONE_HOUR_IN_MILLISEC + ospRule.GetMinute() * ONE_MIN_IN_MILLISEC;
398 int ospTimeMode = ospRule.GetTimeMode();
399 mode = IcuDateTimeRule::WALL_TIME;
400 if (ospTimeMode == Tizen::System::TIME_MODE_UTC)
402 mode = IcuDateTimeRule::UTC_TIME;
405 if (ospTimeMode == Tizen::System::TIME_MODE_STANDARD)
407 mode = IcuDateTimeRule::STANDARD_TIME;
410 switch (ospRule.GetRuleMode())
413 case BACKWARD_FROM_END_OF_MONTH:
416 case DAY_OF_WEEK_IN_MONTH:
417 dayOfWeekInMonth = ospRule.GetWeek();
418 if (dayOfWeekInMonth < 0)
423 case AFTER_THE_SPECIFIED_DAY:
424 case BEFORE_THE_SPECIFIED_DAY:
425 dayOfWeekInMonth *= ospRule.IsOnOrAfterDay()? 1 : -1;
426 dayOfWeek = -dayOfWeek;
433 _TimeZoneImpl::GetTimeRuleFromIcuDateTimeRule(const U_ICU_NAMESPACE::DateTimeRule* pIcuRule, TimeRule& ospRule)
437 Month month = MONTH_UNDEFINED;
438 int icuMonth = pIcuRule->getRuleMonth();
439 if (icuMonth >= 0 && icuMonth <= 11)
441 month = static_cast< Month > (icuMonth + 1);
444 IcuDateTimeRule::DateRuleType dateRuleType = pIcuRule->getDateRuleType();
445 int day = (dateRuleType == IcuDateTimeRule::DOW)? TimeRule::DAY_UNDEFINED : pIcuRule->getRuleDayOfMonth();
447 Week week = WEEK_UNDEFINED;
448 int icuWeek = pIcuRule->getRuleWeekInMonth();
449 if (dateRuleType == IcuDateTimeRule::DOW)
451 week = (icuWeek == -1)? LAST_WEEK : static_cast< Week >(icuWeek);
454 DayOfWeek dayOfWeek = DAY_OF_WEEK_UNDEFINED;
455 if (dateRuleType != IcuDateTimeRule::DOM)
457 dayOfWeek = static_cast< DayOfWeek >(pIcuRule->getRuleDayOfWeek());
460 bool onOrAfterDay = (dateRuleType == IcuDateTimeRule::DOW_LEQ_DOM)? false : true;
462 int ruleMID = pIcuRule->getRuleMillisInDay();
463 int hour = ruleMID / ONE_HOUR_IN_MILLISEC;
464 int minute = (ruleMID % ONE_HOUR_IN_MILLISEC) / ONE_MIN_IN_MILLISEC;
466 Tizen::System::TimeMode timeMode = Tizen::System::TIME_MODE_WALL;
467 IcuDateTimeRule::TimeRuleType timeRuleType = pIcuRule->getTimeRuleType();
468 if (timeRuleType == IcuDateTimeRule::UTC_TIME)
470 timeMode = Tizen::System::TIME_MODE_UTC;
473 if (timeRuleType == IcuDateTimeRule::STANDARD_TIME)
475 timeMode = Tizen::System::TIME_MODE_STANDARD;
478 ospRule.SetValue(month, day, week, dayOfWeek, onOrAfterDay, hour, minute, timeMode);