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_CalendarImpl.cpp
20 * @brief This is the implementation file for _CalendarImpl class.
24 #include <unique_ptr.h>
26 #include <FBaseDateTime.h>
27 #include <FBaseSysLog.h>
28 #include <FApp_AppInfo.h>
29 #include <FLclGregorianCalendar.h>
31 #include "FLcl_CalendarImpl.h"
32 #include "FLcl_IcuCalendarImpl.h"
33 #include "FLcl_LocaleData.h"
34 #include "FLcl_LocaleImpl.h"
35 #include "FLcl_LocaleManagerImpl.h"
37 using namespace Tizen::Base;
39 namespace Tizen { namespace Locales
42 static const int ONE_MINUTE_IN_MILLISEC = 60000;
44 _CalendarImpl::_CalendarImpl()
45 : __type(CALENDAR_GREGORIAN)
46 , __locale(LANGUAGE_INVALID, COUNTRY_INVALID)
52 _CalendarImpl::~_CalendarImpl()
60 _CalendarImpl::CreateCalendarInstanceN(CalendarType calendarType)
62 return CreateInstanceN(TimeZone::GetGmtTimeZone(), calendarType);
66 _CalendarImpl::CreateCalendarInstanceN(const TimeZone& timeZone, CalendarType calendarType)
68 return CreateInstanceN(timeZone, _LocaleManagerImpl::GetSystemLocale(), calendarType);
72 _CalendarImpl::CreateCalendarInstanceN(const Locale& locale, CalendarType calendarType)
74 // Create calendar using system time zone and given locale and calendar type
75 return CreateInstanceN(TimeZone::GetGmtTimeZone(), locale, calendarType);
79 _CalendarImpl::CreateCalendarInstanceN(const TimeZone& timeZone, const Locale& locale, CalendarType calendarType)
85 case CALENDAR_GREGORIAN:
87 std::unique_ptr< GregorianCalendar > pGregCalendar(new (std::nothrow) GregorianCalendar);
88 SysTryReturn(NID_LCL, pGregCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
90 r = pGregCalendar->Construct(timeZone, locale);
91 SysTryReturn(NID_LCL, !IsFailed(r), null, r, "[%s] Unable to construct calendar", GetErrorMessage(r));
93 return pGregCalendar.release();
100 std::unique_ptr< _CalendarImpl > pCalendar(new (std::nothrow) _CalendarImpl);
101 SysTryReturn(NID_LCL, pCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
103 r = pCalendar->Construct(timeZone, locale, calendarType);
105 SysTryReturn(NID_LCL, !IsFailed(r), null, r, "[%s] Unable to construct calendar", GetErrorMessage(r));
106 return pCalendar.release();
110 _CalendarImpl::CloneN(void) const
112 std::unique_ptr< _CalendarImpl > pCalendar(new (std::nothrow) _CalendarImpl());
113 SysTryReturn(NID_LCL, pCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
115 if (__pCalendar != null)
117 pCalendar->__pCalendar = __pCalendar->CloneN();
118 if (pCalendar->__pCalendar != null)
120 pCalendar->__type = __type;
121 pCalendar->__locale = __locale;
122 pCalendar->__timezone = __timezone;
124 pCalendar->_pCalendarImpl = pCalendar.get();
128 return pCalendar.release();
132 _CalendarImpl::Construct(CalendarType calendarType)
134 Locale defaultLocale = _LocaleManagerImpl::GetSystemLocale();
135 return Construct( TimeZone::GetGmtTimeZone(), defaultLocale, calendarType);
139 _CalendarImpl::Construct(const TimeZone& timezone, CalendarType calendarType)
141 Locale defaultLocale = _LocaleManagerImpl::GetSystemLocale();
142 return Construct(timezone, defaultLocale, calendarType);
146 _CalendarImpl::Construct(const Locale& locale, CalendarType calendarType)
148 TimeZone defaultTimeZone = TimeZone::GetGmtTimeZone();
149 return Construct(defaultTimeZone, locale, calendarType);
153 _CalendarImpl::Construct(const TimeZone& timeZone, const Locale& locale, CalendarType calendarType)
155 // Object is not allowed to construct twice
156 SysAssertf(__pCalendar == null,
157 "Already constructed! Calling Construct() twice or more on a same instance is not allowed for this class");
159 SysTryReturnResult(NID_LCL, _LocaleImpl::IsSupported(locale), E_INVALID_ARG, "Given locale is not supported");
161 std::unique_ptr< _IcuCalendarImpl > pCalendar(new (std::nothrow) _IcuCalendarImpl);
162 SysTryReturnResult(NID_LCL, pCalendar != null, E_OUT_OF_MEMORY, "Memory allocation failed");
164 result r = pCalendar->Construct(timeZone, locale, calendarType);
167 __pCalendar = pCalendar.release();
168 __type = calendarType;
170 __timezone = timeZone;
172 _pCalendarImpl = this;
180 _CalendarImpl::Construct(const Calendar& otherCalendar)
182 // Object is not allowed to construct twice
183 SysAssertf(__pCalendar == null,
184 "Already constructed! Calling Construct() twice or more on a same instance is not allowed for this class");
187 const _CalendarImpl* pOtherCalendar = dynamic_cast< const _CalendarImpl* >(&otherCalendar);
188 if ((pOtherCalendar != null) && (pOtherCalendar->__pCalendar != null))
192 __pCalendar = pOtherCalendar->__pCalendar->CloneN();
193 if (__pCalendar != null)
195 __type = pOtherCalendar->__type;
196 __locale = pOtherCalendar->__locale;
197 __timezone = pOtherCalendar->__timezone;
199 _pCalendarImpl = pOtherCalendar->_pCalendarImpl;
208 _CalendarImpl::SetTimeFieldImpl(TimeField field, int value)
210 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
211 SysTryReturnResult(NID_LCL, ValidateTimeField(field),
212 E_INVALID_ARG, "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
213 SysTryReturnResult(NID_LCL, ValidateTimeFieldValue(field, value), E_OUT_OF_RANGE, "value(%d) is out of range.", value);
215 return __pCalendar->SetTimeField(field, value);
219 _CalendarImpl::SetTimeInMillisecImpl(long long millisec)
221 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
222 return __pCalendar->SetTimeInMillisec(millisec - __timezone.GetRawOffset() * ONE_MINUTE_IN_MILLISEC);
226 _CalendarImpl::SetTimeImpl(const DateTime& dateTime)
228 return SetTimeImpl(dateTime.GetYear(), dateTime.GetMonth(), dateTime.GetDay(),
229 dateTime.GetHour(), dateTime.GetMinute(), dateTime.GetSecond(), dateTime.GetMillisecond());
233 _CalendarImpl::SetTimeImpl(int year, int month, int day, int hour, int minute, int second, int millisecond)
235 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
236 return __pCalendar->SetTime(year, month, day, hour, minute, second, millisecond);
240 _CalendarImpl::SetFirstDayOfWeekImpl(DayOfWeek dayOfWeek)
242 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
243 SysTryReturnResult(NID_LCL, ValidateDaysOfWeek(dayOfWeek), E_INVALID_ARG, "Invalid argument is used. Unknown day of week");
245 return __pCalendar->SetFirstDayOfWeek(dayOfWeek);
249 _CalendarImpl::SetLenientImpl(bool lenient)
251 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
252 return __pCalendar->SetLenient(lenient);
256 _CalendarImpl::SetMinDaysInFirstWeekImpl(short value)
258 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
259 return __pCalendar->SetMinDaysInFirstWeek(value);
263 _CalendarImpl::SetTimeZoneImpl(const TimeZone& timeZone)
265 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
267 _timeZone = timeZone;
268 __timezone = timeZone;
269 return __pCalendar->SetTimeZone(__timezone);
273 _CalendarImpl::ClearImpl(void)
275 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
276 return __pCalendar->Clear();
280 _CalendarImpl::ClearImpl(TimeField field)
282 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
283 SysTryReturnResult(NID_LCL, ValidateTimeField(field), E_INVALID_ARG,
284 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
286 return __pCalendar->Clear(field);
290 _CalendarImpl::AddTimeField(TimeField field, int amount)
292 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
294 result r = E_INVALID_ARG;
296 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
301 SysTryReturnResult(NID_LCL, ValidateTimeField(field), r,
302 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
304 return __pCalendar->AddTimeField(field, amount);
308 _CalendarImpl::Roll(TimeField field, int amount)
310 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
312 result r = E_INVALID_ARG;
313 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
318 SysTryReturnResult(NID_LCL, ValidateTimeField(field), r,
319 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
321 return __pCalendar->Roll(field, amount);
325 _CalendarImpl::After(const _CalendarImpl& otherInstance, bool& after)
327 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
329 result r = E_INVALID_ARG;
330 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
335 SysTryReturnResult(NID_LCL, otherInstance.__pCalendar, r, "Invalid argument is used. otherCalendar instance is invalid");
337 return __pCalendar->After(*(otherInstance.__pCalendar), after);
341 _CalendarImpl::Before(const _CalendarImpl& otherInstance, bool& before)
343 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
345 result r = E_INVALID_ARG;
346 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
351 SysTryReturnResult(NID_LCL, otherInstance.__pCalendar, r, "Invalid argument is used. otherCalendar instance is invalid");
353 return __pCalendar->Before(*(otherInstance.__pCalendar), before);
357 _CalendarImpl::Equals(const _CalendarImpl& otherInstance) const
359 if ((__pCalendar != null) && (otherInstance.__pCalendar != null))
361 return __pCalendar->Equals(*(otherInstance.__pCalendar));
363 return (__pCalendar == otherInstance.__pCalendar);
367 _CalendarImpl::GetHashCode(void) const
369 Integer intValues = IsLenient() + GetFirstDayOfWeek() + GetMinDaysInFirstWeek();
370 int hashCode = intValues.GetHashCode();
372 long long myTicks = 0;
373 GetTimeInMillisec(myTicks);
374 hashCode = (hashCode << 5) - hashCode + LongLong(myTicks).GetHashCode()+__timezone.GetHashCode();
380 _CalendarImpl::GetType(void) const
386 _CalendarImpl::GetTimeFieldImpl(TimeField field) const
388 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
389 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
390 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
392 return __pCalendar->GetTimeField(field);
396 _CalendarImpl::GetTimeInMillisecImpl(long long& millisec) const
398 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
400 long long tempMillisec;
402 r = __pCalendar->GetTimeInMillisec(tempMillisec);
403 SysTryReturnResult(NID_LCL, r == E_SUCCESS, r, "Unable to get time in milli sec");
404 millisec = tempMillisec + __timezone.GetRawOffset() * ONE_MINUTE_IN_MILLISEC;
409 _CalendarImpl::GetTimeImpl(void) const
411 int year = __pCalendar->GetTimeField(TIME_FIELD_YEAR);
412 int month = __pCalendar->GetTimeField(TIME_FIELD_MONTH);
413 int date = __pCalendar->GetTimeField(TIME_FIELD_DAY_OF_MONTH);
415 int hour = __pCalendar->GetTimeField(TIME_FIELD_HOUR_OF_DAY);
416 int minute = __pCalendar->GetTimeField(TIME_FIELD_MINUTE);
417 int second = __pCalendar->GetTimeField(TIME_FIELD_SECOND);
418 int millisecond = __pCalendar->GetTimeField(TIME_FIELD_MILLISECOND);
421 result r = dateTime.SetValue(year, month, date, hour, minute, second, millisecond);
422 SysTryReturn(NID_LCL, r == E_SUCCESS, DateTime(), r, "[%s] Unable to set time in DateTime object", GetErrorMessage(r));
428 _CalendarImpl::GetMinTimeField(TimeField field) const
430 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
431 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
432 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
434 return __pCalendar->GetMinTimeField(field);
438 _CalendarImpl::GetActualMinTimeField(TimeField field) const
440 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
441 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
442 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
444 return __pCalendar->GetActualMinTimeField(field);
448 _CalendarImpl::GetGreatestMinTimeField(TimeField field) const
450 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
451 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
452 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
454 return __pCalendar->GetGreatestMinTimeField(field);
458 _CalendarImpl::GetLeastMaxTimeField(TimeField field) const
460 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
461 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
462 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
464 return __pCalendar->GetLeastMaxTimeField(field);
468 _CalendarImpl::GetActualMaxTimeField(TimeField field) const
470 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
471 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
472 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
474 return __pCalendar->GetActualMaxTimeField(field);
478 _CalendarImpl::GetMaxTimeField(TimeField field) const
480 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
481 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
482 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
484 return __pCalendar->GetMaxTimeField(field);
488 _CalendarImpl::GetFirstDayOfWeekImpl(void) const
490 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
491 return __pCalendar->GetFirstDayOfWeek();
495 _CalendarImpl::GetMinDaysInFirstWeekImpl(void) const
497 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
498 return __pCalendar->GetMinDaysInFirstWeek();
502 _CalendarImpl::IsInDst(bool& isInDst) const
504 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
505 return __pCalendar->IsInDst(isInDst);
509 _CalendarImpl::IsLenientImpl(void) const
511 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
512 return __pCalendar->IsLenient();
516 _CalendarImpl::IsSetImpl(TimeField field) const
518 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
519 return __pCalendar->IsSet(field);
523 _CalendarImpl::GetTimeZoneImpl(void) const
529 _CalendarImpl::IsLeapYear(int year) const
531 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
532 return __pCalendar->IsLeapYear(year);
536 _CalendarImpl::SetGregorianChange(long long change)
538 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
539 return __pCalendar->SetGregorianChange(change);
543 _CalendarImpl::GetGregorianChange(void) const
545 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
546 return __pCalendar->GetGregorianChange();
550 _CalendarImpl::SetJulianDay(int julianDay)
552 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
553 return __pCalendar->SetJulianDay(julianDay);
557 _CalendarImpl::GetJulianDay(void) const
559 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
560 return __pCalendar->GetJulianDay();
564 _CalendarImpl::ValidateTimeField(TimeField field) const
566 if (field < 0 || field >= TIME_FIELD_FIELD_COUNT)
574 _CalendarImpl::ValidateTimeFieldValue(TimeField field, int value) const
576 if (IsLenientImpl() == false)
578 if ((value < GetMinTimeField(field)) || (value > GetMaxTimeField(field)))
588 _CalendarImpl::ValidateDaysOfWeek(DayOfWeek dayOfWeek) const
590 if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY)
597 // added for backward compatibility
599 _CalendarImpl::RollWithSingleUnit(TimeField field, bool up)
601 return E_UNSUPPORTED_OPERATION;
604 // added for backward compatibility
606 _CalendarImpl::ComputeTimeFields(void)
608 return E_UNSUPPORTED_OPERATION;
611 // added for backward compatibility
613 _CalendarImpl::ComputeTime(void)
615 return E_UNSUPPORTED_OPERATION;
618 // added for backward compatibility
620 _CalendarImpl::GetMonthLength(int extendedYear, int month) const
622 SetLastResult(E_UNSUPPORTED_OPERATION);
626 // added for backward compatibility
628 _CalendarImpl::HandleGetLimit(TimeField field, CalendarLimitType limitType) const
630 SetLastResult(E_UNSUPPORTED_OPERATION);
634 const _IcuCalendarImpl*
635 _CalendarImpl::GetImpl(const Calendar& calendar)
637 if (calendar._pCalendarImpl)
639 return calendar._pCalendarImpl->__pCalendar;