Merge "add cleanup for osp-appfw unload" into devel_3.0_main
[platform/framework/native/appfw.git] / src / locales / FLcl_TimeZoneImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file            FLcl_TimeZoneImpl.cpp
19  * @brief           This is the implementation file for _TimeZoneImpl class.
20  */
21
22 #include <unique_ptr.h>
23 #include <unicode/timezone.h>
24 #include <unicode/basictz.h>
25 #include <unicode/simpletz.h>
26 #include <unicode/tztrans.h>
27 #include <unicode/tzrule.h>
28
29 #include <FBaseInteger.h>
30 #include <FBaseSysLog.h>
31 #include <FLclTimeZone.h>
32
33 #include "FLcl_LocaleData.h"
34 #include "FLcl_TimeZoneImpl.h"
35
36 typedef U_ICU_NAMESPACE::TimeZone IcuTimeZone;
37 typedef U_ICU_NAMESPACE::BasicTimeZone IcuBasicTimeZone;
38 typedef U_ICU_NAMESPACE::SimpleTimeZone IcuSimpleTimeZone;
39 typedef U_ICU_NAMESPACE::InitialTimeZoneRule IcuInitialTimeZoneRule;
40 typedef U_ICU_NAMESPACE::AnnualTimeZoneRule IcuAnnualTimeZoneRule;
41 typedef U_ICU_NAMESPACE::DateTimeRule IcuDateTimeRule;
42
43 enum DstRuleMode
44 {
45         EXACT_DAY = 0,
46         DAY_OF_WEEK_IN_MONTH,
47         AFTER_THE_SPECIFIED_DAY,
48         BEFORE_THE_SPECIFIED_DAY,
49         BACKWARD_FROM_END_OF_MONTH
50 };
51
52 using namespace Tizen::Base;
53
54 namespace Tizen { namespace Locales
55 {
56
57 _TimeZoneImpl::_TimeZoneImpl(void)
58         : __pIcuTimeZone(null)
59         , __dstSaving(60)
60         , __dstStartingYear(0)
61         , __startingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
62         , __endingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
63         , __isCustomizing(true)
64 {
65         __pIcuTimeZone = new U_ICU_NAMESPACE::SimpleTimeZone(0, "");
66         SysTryReturn(NID_LCL, __pIcuTimeZone, , E_OUT_OF_MEMORY, "It is not enough memory.");
67 }
68
69 _TimeZoneImpl::_TimeZoneImpl(int rawOffset, const String& id)
70         : __pIcuTimeZone(null)
71         , __dstSaving(60)
72         , __dstStartingYear(0)
73         , __startingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
74         , __endingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
75         , __isCustomizing(true)
76 {
77         UnicodeString icuId(_LocaleData::GetIcuString(id));
78         __pIcuTimeZone = new U_ICU_NAMESPACE::SimpleTimeZone(rawOffset * ONE_MIN_IN_MILLISEC, icuId);
79         SysTryReturn(NID_LCL, __pIcuTimeZone, , E_OUT_OF_MEMORY, "It is not enough memory.");
80 }
81
82 _TimeZoneImpl::_TimeZoneImpl(int rawOffset, const String& id, const TimeRule& startRule, const TimeRule& endRule, int dstOffset)
83         : __pIcuTimeZone(null)
84         , __dstSaving(dstOffset)
85         , __dstStartingYear(0)
86         , __startingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
87         , __endingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
88         , __isCustomizing(true)
89 {
90         UnicodeString icuId(_LocaleData::GetIcuString(id));
91         __pIcuTimeZone = new U_ICU_NAMESPACE::SimpleTimeZone(rawOffset * ONE_MIN_IN_MILLISEC, icuId);
92         SysTryReturn(NID_LCL, __pIcuTimeZone, , E_OUT_OF_MEMORY, "It is not enough memory.");
93         SetDstRules(startRule, endRule, dstOffset);
94 }
95
96 _TimeZoneImpl::_TimeZoneImpl(const _TimeZoneImpl& otherTimeZone)
97         : __pIcuTimeZone(null)
98         , __dstSaving(otherTimeZone.__dstSaving)
99         , __dstStartingYear(otherTimeZone.__dstStartingYear)
100         , __startingRule(otherTimeZone.__startingRule)
101         , __endingRule(otherTimeZone.__endingRule)
102         , __isCustomizing(otherTimeZone.__isCustomizing)
103 {
104         __pIcuTimeZone = otherTimeZone.__pIcuTimeZone->clone();
105         SysTryReturn(NID_LCL, __pIcuTimeZone, , E_OUT_OF_MEMORY, "It is not enough memory.");
106 }
107
108 _TimeZoneImpl::_TimeZoneImpl(U_ICU_NAMESPACE::TimeZone* pIcuTimeZone)
109         : __pIcuTimeZone(null)
110         , __dstSaving(60)
111         , __dstStartingYear(0)
112         , __startingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
113         , __endingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
114         , __isCustomizing(true)
115 {
116         __pIcuTimeZone = pIcuTimeZone;
117 }
118
119 _TimeZoneImpl::_TimeZoneImpl(U_ICU_NAMESPACE::TimeZone* pIcuTimeZone, UDate icuDate)
120         : __pIcuTimeZone(null)
121         , __dstSaving(60)
122         , __dstStartingYear(0)
123         , __startingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
124         , __endingRule(MONTH_UNDEFINED, DAY_UNDEFINED)
125         , __isCustomizing(false)
126 {
127         __pIcuTimeZone = pIcuTimeZone;
128         U_ICU_NAMESPACE::BasicTimeZone* pIcuTz = dynamic_cast<U_ICU_NAMESPACE::BasicTimeZone*>(pIcuTimeZone);
129         if (pIcuTz)
130         {
131                 UErrorCode status = U_ZERO_ERROR;
132                 U_ICU_NAMESPACE::InitialTimeZoneRule* pInitial = null;
133                 U_ICU_NAMESPACE::AnnualTimeZoneRule* pStd = null;
134                 U_ICU_NAMESPACE::AnnualTimeZoneRule* pDst = null;
135                 pIcuTz->getSimpleRulesNear(icuDate, pInitial, pStd, pDst, status);
136
137                 if (pStd && pDst)
138                 {
139                         result r = GetTimeRuleFromIcuDateTimeRule(pDst->getRule(), __startingRule);
140                         if (r == E_SUCCESS)
141                         {
142                                 GetTimeRuleFromIcuDateTimeRule(pStd->getRule(), __endingRule);
143                                 __dstStartingYear = pDst->getStartYear();
144                                 __dstSaving = pIcuTz->getDSTSavings() / ONE_MIN_IN_MILLISEC;
145                         }
146                 }
147                 else
148                 {
149                         U_ICU_NAMESPACE::TimeZoneTransition transition;
150                         bool result = pIcuTz->getPreviousTransition(icuDate, true, transition);
151                         if (result)
152                         {
153                                 const U_ICU_NAMESPACE::TimeZoneRule* pTzFromRule = transition.getFrom();
154                                 const U_ICU_NAMESPACE::TimeZoneRule* pTzToRule = transition.getTo();
155
156                                 if (pTzFromRule->getDSTSavings())
157                                 {
158                                         __dstSaving = pTzFromRule->getDSTSavings() / ONE_MIN_IN_MILLISEC;
159                                 }
160                                 else if (pTzToRule->getDSTSavings())
161                                 {
162                                         __dstSaving = pTzToRule->getDSTSavings() / ONE_MIN_IN_MILLISEC;
163                                 }
164                                 else //if (pTzFromRule->getDSTSavings() == 0 && pTzToRule->getDSTSavings() == 0)
165                                 {
166                                         __dstSaving = 0;
167                                 }
168                         }
169                 }
170                 delete pInitial;
171                 delete pStd;
172                 delete pDst;
173         }
174 }
175
176 _TimeZoneImpl*
177 _TimeZoneImpl::CloneN(void)
178 {
179         return new (std::nothrow) _TimeZoneImpl(*this);
180 }
181
182 _TimeZoneImpl&
183 _TimeZoneImpl::operator =(const _TimeZoneImpl& otherTimeZone)
184 {
185         if (*this != otherTimeZone)
186         {
187                 __pIcuTimeZone = otherTimeZone.__pIcuTimeZone;
188                 __dstSaving = otherTimeZone.__dstSaving;
189                 __dstStartingYear = otherTimeZone.__dstStartingYear;
190                 __startingRule = otherTimeZone.__startingRule;
191                 __endingRule = otherTimeZone.__endingRule;
192                 __isCustomizing = otherTimeZone.__isCustomizing;
193         }
194         return *this;
195 }
196
197 _TimeZoneImpl::~_TimeZoneImpl(void)
198 {
199         if (__pIcuTimeZone)
200         {
201                 delete __pIcuTimeZone;
202         }
203 }
204
205 U_ICU_NAMESPACE::TimeZone*
206 _TimeZoneImpl::GetIcuTimeZone(void) const
207 {
208         return __pIcuTimeZone;
209 }
210
211
212 bool
213 _TimeZoneImpl::operator ==(const _TimeZoneImpl& otherTimeZone) const
214 {
215         return *__pIcuTimeZone == *otherTimeZone.__pIcuTimeZone;
216 }
217
218 bool
219 _TimeZoneImpl::operator !=(const _TimeZoneImpl& otherTimeZone) const
220 {
221         return !(*this == otherTimeZone);
222 }
223
224 bool
225 _TimeZoneImpl::Equals(const Object& obj) const
226 {
227         const _TimeZoneImpl* pTimeZoneImpl = dynamic_cast<const _TimeZoneImpl*>(&obj);
228         if (pTimeZoneImpl)
229         {
230                 return (*this == *pTimeZoneImpl);
231         }
232         return false;
233 }
234
235 int
236 _TimeZoneImpl::GetHashCode(void) const
237 {
238         int hashCode = GetId().GetHashCode();
239         int customizing = (__isCustomizing == false) ? 0 : __dstStartingYear;
240         Integer intValues = GetRawOffset() + GetDstSavings() + IsDstUsed() + customizing;
241         hashCode = (hashCode << 5) - hashCode + intValues.GetHashCode();
242         hashCode = (hashCode << 5) - hashCode + __startingRule.GetHashCode();
243         hashCode = (hashCode << 5) - hashCode + __endingRule.GetHashCode();
244
245         return hashCode;
246 }
247
248 String
249 _TimeZoneImpl::GetId(void) const
250 {
251         U_ICU_NAMESPACE::UnicodeString icuStr;
252         __pIcuTimeZone->getID(icuStr);
253         return _LocaleData::GetOspString(icuStr);
254 }
255
256 void
257 _TimeZoneImpl::SetId(const String& id)
258 {
259         U_ICU_NAMESPACE::UnicodeString icuStr = _LocaleData::GetIcuString(id);
260         __pIcuTimeZone->setID(icuStr);
261 }
262
263 int
264 _TimeZoneImpl::GetRawOffset(void) const
265 {
266         return __pIcuTimeZone->getRawOffset() / ONE_MIN_IN_MILLISEC;
267 }
268
269 void
270 _TimeZoneImpl::SetRawOffset(int rawOffset)
271 {
272         __pIcuTimeZone->setRawOffset(rawOffset * ONE_MIN_IN_MILLISEC);
273 }
274
275 int
276 _TimeZoneImpl::GetDstStartingYear(void) const
277 {
278         return __dstStartingYear;
279 }
280
281 void
282 _TimeZoneImpl::SetDstStartingYear(int year)
283 {
284         __dstStartingYear = year;
285         U_ICU_NAMESPACE::SimpleTimeZone* pStz = dynamic_cast<U_ICU_NAMESPACE::SimpleTimeZone*>(__pIcuTimeZone);
286
287         if (pStz == null)
288         {
289                 U_ICU_NAMESPACE::UnicodeString id;
290                 __pIcuTimeZone->getID(id);
291                 pStz = new U_ICU_NAMESPACE::SimpleTimeZone(__pIcuTimeZone->getRawOffset(), id);
292                 SysTryReturn(NID_LCL, pStz, ,E_OUT_OF_MEMORY, "It is not enough memory.");
293                 delete __pIcuTimeZone;
294                 __pIcuTimeZone = pStz;
295         }
296
297         pStz->setStartYear(year);
298         __isCustomizing = true;
299 }
300
301 int
302 _TimeZoneImpl::GetDstSavings(void) const
303 {
304         if (__isCustomizing)
305         {
306                 return __pIcuTimeZone->getDSTSavings() / ONE_MIN_IN_MILLISEC;
307         }
308         return __dstSaving;
309 }
310
311 void
312 _TimeZoneImpl::SetDstSavings(int dstSavings)
313 {
314         UErrorCode ec = U_ZERO_ERROR;
315
316         U_ICU_NAMESPACE::SimpleTimeZone* pStz = dynamic_cast<U_ICU_NAMESPACE::SimpleTimeZone*>(__pIcuTimeZone);
317
318         if (pStz == null)
319         {
320                 U_ICU_NAMESPACE::UnicodeString id;
321                 __pIcuTimeZone->getID(id);
322                 pStz = new U_ICU_NAMESPACE::SimpleTimeZone(__pIcuTimeZone->getRawOffset(), id);
323                 SysTryReturn(NID_LCL, pStz, ,E_OUT_OF_MEMORY, "It is not enough memory.");
324                 delete __pIcuTimeZone;
325                 __pIcuTimeZone = pStz;
326         }
327         pStz->setDSTSavings(dstSavings * ONE_MIN_IN_MILLISEC, ec);
328         __dstSaving = dstSavings;
329         __isCustomizing = true;
330 }
331
332 const TimeRule*
333 _TimeZoneImpl::GetDstStartingRule(void) const
334 {
335         return __startingRule.GetMonth() != MONTH_UNDEFINED ? &__startingRule : null;
336 }
337
338 void
339 _TimeZoneImpl::SetDstStartingRule(const TimeRule& startRule)
340 {
341         int month = 0;
342         int dayOfWeekInMonth = 0;
343         int dayOfWeek = 0;
344         int time = 0;
345         int mode = 0;
346
347         UErrorCode ec = U_ZERO_ERROR;
348         GetIcuTimeRuleValue(startRule, month, dayOfWeekInMonth, dayOfWeek, time, mode);
349
350         U_ICU_NAMESPACE::SimpleTimeZone::TimeMode timeMode = static_cast<U_ICU_NAMESPACE::SimpleTimeZone::TimeMode> (mode);
351         U_ICU_NAMESPACE::SimpleTimeZone* pStz = dynamic_cast<U_ICU_NAMESPACE::SimpleTimeZone*>(__pIcuTimeZone);
352
353         if (pStz == null)
354         {
355                 U_ICU_NAMESPACE::UnicodeString id;
356                 __pIcuTimeZone->getID(id);
357                 pStz = new U_ICU_NAMESPACE::SimpleTimeZone(__pIcuTimeZone->getRawOffset(), id);
358                 SysTryReturn(NID_LCL, pStz, ,E_OUT_OF_MEMORY, "It is not enough memory.");
359                 delete __pIcuTimeZone;
360                 __pIcuTimeZone = pStz;
361         }
362
363         pStz->setStartRule(month, dayOfWeekInMonth, dayOfWeek, time, timeMode, ec);
364         __startingRule = startRule;
365         __isCustomizing = true;
366 }
367
368 const TimeRule*
369 _TimeZoneImpl::GetDstEndingRule(void) const
370 {
371         return __endingRule.GetMonth() != MONTH_UNDEFINED ? &__endingRule : null;
372 }
373
374 void
375 _TimeZoneImpl::SetDstEndingRule(const TimeRule& endRule)
376 {
377         int month = 0;
378         int dayOfWeekInMonth = 0;
379         int dayOfWeek = 0;
380         int time = 0;
381         int mode = 0;
382
383         UErrorCode ec = U_ZERO_ERROR;
384         GetIcuTimeRuleValue(endRule, month, dayOfWeekInMonth, dayOfWeek, time, mode);
385
386         U_ICU_NAMESPACE::SimpleTimeZone::TimeMode timeMode = static_cast<U_ICU_NAMESPACE::SimpleTimeZone::TimeMode> (mode);
387         U_ICU_NAMESPACE::SimpleTimeZone* pStz = dynamic_cast<U_ICU_NAMESPACE::SimpleTimeZone*>(__pIcuTimeZone);
388
389         if (pStz == null)
390         {
391                 U_ICU_NAMESPACE::UnicodeString id;
392                 __pIcuTimeZone->getID(id);
393                 pStz = new U_ICU_NAMESPACE::SimpleTimeZone(__pIcuTimeZone->getRawOffset(), id);
394                 SysTryReturn(NID_LCL, pStz, ,E_OUT_OF_MEMORY, "It is not enough memory.");
395                 delete __pIcuTimeZone;
396                 __pIcuTimeZone = pStz;
397         }
398
399         pStz->setEndRule(month, dayOfWeekInMonth, dayOfWeek, time, timeMode, ec);
400         __endingRule = endRule;
401         __isCustomizing = true;
402 }
403
404 result
405 _TimeZoneImpl::SetDstRules(const TimeRule& startRule, const TimeRule& endRule, int dstSavings)
406 {
407         SysTryReturnResult(NID_LCL, dstSavings >= 0,
408                         E_OUT_OF_RANGE, "dstSavings [%d] should be greater or equal to than 0", dstSavings);
409         SysTryReturnResult(NID_LCL, dstSavings < ONE_DAY_IN_MINUTE,
410                         E_OUT_OF_RANGE, "dstSavings [%d] should be greater than %d", dstSavings, ONE_DAY_IN_MINUTE);
411         SetDstStartingRule(startRule);
412         SetDstEndingRule(endRule);
413         SetDstSavings(dstSavings);
414         return E_SUCCESS;
415 }
416
417 result
418 _TimeZoneImpl::GetOffset(const DateTime& date, bool local, int& rawOffset, int& dstOffset) const
419 {
420         UErrorCode ec = U_ZERO_ERROR;
421         __pIcuTimeZone->getOffset(_LocaleData::GetIcuDate(date), local, rawOffset, dstOffset, ec);
422         rawOffset /= ONE_MIN_IN_MILLISEC;
423         dstOffset /= ONE_MIN_IN_MILLISEC;
424         return U_SUCCESS(ec) ? E_SUCCESS : E_INVALID_ARG;
425 }
426
427 result
428 _TimeZoneImpl::GetOffset(long long ticks, int& offset) const
429 {
430         TimeSpan ts(ticks);
431         DateTime date;
432         result r = date.SetValue(ts.GetTicks());
433         SysTryReturnResult(NID_LCL, r == E_SUCCESS, E_INVALID_ARG, "It is an invalid argument.");
434
435         int rawOffset = 0;
436         int dstOffset = 0;
437         UErrorCode ec = U_ZERO_ERROR;
438         __pIcuTimeZone->getOffset(_LocaleData::GetIcuDate(date), false, rawOffset, dstOffset, ec);
439         offset = (rawOffset + dstOffset) / ONE_MIN_IN_MILLISEC;
440         return U_SUCCESS(ec) ? E_SUCCESS : E_INVALID_ARG;
441 }
442
443 bool
444 _TimeZoneImpl::IsDstUsed(void) const
445 {
446         return __pIcuTimeZone->useDaylightTime();
447 }
448
449 const _TimeZoneImpl*
450 _TimeZoneImpl::GetTimeZoneImpl(const TimeZone& ospTimeZone)
451 {
452         return ospTimeZone.__pTimeZoneImpl;
453 }
454
455 result
456 _TimeZoneImpl::GetTimeZone(const String& id, Tizen::Locales::TimeZone& timeZone)
457 {
458         U_ICU_NAMESPACE::UnicodeString icuStr = _LocaleData::GetIcuString(id);
459         std::unique_ptr<U_ICU_NAMESPACE::TimeZone> pIcuTimeZone(U_ICU_NAMESPACE::TimeZone::createTimeZone(icuStr));
460         SysTryReturnResult(NID_LCL, pIcuTimeZone != null, E_INVALID_ARG, "Unable to create ICU timezone");
461
462         U_ICU_NAMESPACE::UnicodeString retIcuStr;
463         SysTryReturnResult(NID_LCL, pIcuTimeZone->getID(retIcuStr) == icuStr,
464                                 E_INVALID_ARG, "Unsupported timezone id [%ls]", id.GetPointer());
465
466         std::unique_ptr<U_ICU_NAMESPACE::SimpleTimeZone> pIcuSimpleTimeZone(new U_ICU_NAMESPACE::SimpleTimeZone(pIcuTimeZone->getRawOffset(), icuStr));
467         SysTryReturnResult(NID_LCL, pIcuSimpleTimeZone, E_OUT_OF_MEMORY, "It is enough memory.");
468         std::unique_ptr<_TimeZoneImpl> pTimeZoneImpl(new (std::nothrow) _TimeZoneImpl(pIcuSimpleTimeZone.get()));
469         SysTryReturnResult(NID_LCL, pTimeZoneImpl, E_OUT_OF_MEMORY, "It is enough memory.");
470
471         delete timeZone.__pTimeZoneImpl;
472         timeZone.__pTimeZoneImpl = pTimeZoneImpl.release();
473         pIcuSimpleTimeZone.release();
474         return E_SUCCESS;
475 }
476
477 result
478 _TimeZoneImpl::GetTimeZone(const String& id, const DateTime& utcTime, Tizen::Locales::TimeZone& timeZone)
479 {
480         U_ICU_NAMESPACE::UnicodeString icuStr = _LocaleData::GetIcuString(id);
481         std::unique_ptr<U_ICU_NAMESPACE::TimeZone> pIcuTimeZone(U_ICU_NAMESPACE::TimeZone::createTimeZone(icuStr));
482         SysTryReturnResult(NID_LCL, pIcuTimeZone != null, E_INVALID_ARG, "Unable to create ICU timezone");
483
484         U_ICU_NAMESPACE::UnicodeString retIcuStr;
485         SysTryReturnResult(NID_LCL, pIcuTimeZone->getID(retIcuStr) == icuStr,
486                                 E_INVALID_ARG, "Unsupported timezone id [%ls]", id.GetPointer());
487
488         std::unique_ptr<_TimeZoneImpl> pTimeZoneImpl(new (std::nothrow) _TimeZoneImpl(pIcuTimeZone.get(), _LocaleData::GetIcuDate(utcTime)));
489         SysTryReturnResult(NID_LCL, pTimeZoneImpl, E_OUT_OF_MEMORY, "It is enough memory.");
490
491         delete timeZone.__pTimeZoneImpl;
492         timeZone.__pTimeZoneImpl = pTimeZoneImpl.release();
493         pIcuTimeZone.release();
494         return E_SUCCESS;
495 }
496
497 void
498 _TimeZoneImpl::GetIcuTimeRuleValue(const TimeRule& ospRule, int& month, int& dayOfWeekInMonth, int& dayOfWeek, int& time, int& mode)
499 {
500         if (ospRule.GetMonth() != MONTH_UNDEFINED)
501         {
502                 month = ospRule.GetMonth() - 1;
503
504                 int ospDay = ospRule.GetDay();
505                 dayOfWeekInMonth = (ospDay == TimeRule::DAY_UNDEFINED)? 0 : ospDay;
506
507                 int ospDayOfWeek =  ospRule.GetDayOfWeek();
508                 dayOfWeek = (ospDayOfWeek == WEEK_UNDEFINED)? 0 : ospDayOfWeek;
509
510                 time = ospRule.GetHour() * ONE_HOUR_IN_MILLISEC + ospRule.GetMinute() * ONE_MIN_IN_MILLISEC;
511
512                 int ospTimeMode = ospRule.GetTimeMode();
513                 mode = IcuDateTimeRule::WALL_TIME;
514                 if (ospTimeMode == Tizen::System::TIME_MODE_UTC)
515                 {
516                         mode = IcuDateTimeRule::UTC_TIME;
517                 }
518
519                 if (ospTimeMode == Tizen::System::TIME_MODE_STANDARD)
520                 {
521                         mode = IcuDateTimeRule::STANDARD_TIME;
522                 }
523
524                 switch (ospRule.GetRuleMode())
525                 {
526                 case EXACT_DAY:
527                 case BACKWARD_FROM_END_OF_MONTH:
528                         dayOfWeek = 0;
529                         break;
530                 case DAY_OF_WEEK_IN_MONTH:
531                         dayOfWeekInMonth = ospRule.GetWeek();
532                         if (dayOfWeekInMonth < 0)
533                         {
534                                 ++dayOfWeekInMonth;
535                         }
536                         break;
537                 case AFTER_THE_SPECIFIED_DAY:
538                 case BEFORE_THE_SPECIFIED_DAY:
539                         dayOfWeekInMonth *= ospRule.IsOnOrAfterDay()? 1 : -1;
540                         dayOfWeek = -dayOfWeek;
541                         break;
542                 }
543         }
544 }
545
546 result
547 _TimeZoneImpl::GetTimeRuleFromIcuDateTimeRule(const U_ICU_NAMESPACE::DateTimeRule* pIcuRule, TimeRule& ospRule)
548 {
549         if (pIcuRule)
550         {
551                 Month month = MONTH_UNDEFINED;
552                 int icuMonth = pIcuRule->getRuleMonth();
553                 if (icuMonth >= 0 && icuMonth <= 11)
554                 {
555                         month = static_cast< Month > (icuMonth + 1);
556                 }
557
558                 IcuDateTimeRule::DateRuleType dateRuleType = pIcuRule->getDateRuleType();
559                 int day = (dateRuleType == IcuDateTimeRule::DOW)? TimeRule::DAY_UNDEFINED : pIcuRule->getRuleDayOfMonth();
560
561                 Week week = WEEK_UNDEFINED;
562                 int icuWeek = pIcuRule->getRuleWeekInMonth();
563                 if (dateRuleType == IcuDateTimeRule::DOW)
564                 {
565                         week = (icuWeek == -1)? LAST_WEEK : static_cast< Week >(icuWeek);
566                 }
567
568                 DayOfWeek dayOfWeek = DAY_OF_WEEK_UNDEFINED;
569                 if (dateRuleType != IcuDateTimeRule::DOM)
570                 {
571                         dayOfWeek = static_cast< DayOfWeek >(pIcuRule->getRuleDayOfWeek());
572                 }
573
574                 bool onOrAfterDay = (dateRuleType == IcuDateTimeRule::DOW_LEQ_DOM)? false : true;
575
576                 int ruleMID = pIcuRule->getRuleMillisInDay();
577                 int hour = ruleMID / ONE_HOUR_IN_MILLISEC;
578                 int minute = (ruleMID % ONE_HOUR_IN_MILLISEC) / ONE_MIN_IN_MILLISEC;
579
580                 Tizen::System::TimeMode timeMode = Tizen::System::TIME_MODE_WALL;
581                 IcuDateTimeRule::TimeRuleType timeRuleType = pIcuRule->getTimeRuleType();
582                 if (timeRuleType == IcuDateTimeRule::UTC_TIME)
583                 {
584                         timeMode = Tizen::System::TIME_MODE_UTC;
585                 }
586
587                 if (timeRuleType == IcuDateTimeRule::STANDARD_TIME)
588                 {
589                         timeMode = Tizen::System::TIME_MODE_STANDARD;
590                 }
591
592                 ospRule.SetValue(month, day, week, dayOfWeek, onOrAfterDay, hour, minute, timeMode);
593
594                 return E_SUCCESS;
595         }
596
597         return E_FAILURE;
598 }
599
600 };
601 };      // Tizen::Locales