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::RollImpl(TimeField field, int amount)
310 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
311 result r = E_INVALID_ARG;
312 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
317 SysTryReturnResult(NID_LCL, ValidateTimeField(field), r,
318 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
320 return __pCalendar->Roll(field, amount);
324 _CalendarImpl::After(const _CalendarImpl& otherInstance, bool& after)
326 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
328 result r = E_INVALID_ARG;
329 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
334 SysTryReturnResult(NID_LCL, otherInstance.__pCalendar, r, "Invalid argument is used. otherCalendar instance is invalid");
336 return __pCalendar->After(*(otherInstance.__pCalendar), after);
340 _CalendarImpl::Before(const _CalendarImpl& otherInstance, bool& before)
342 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
344 result r = E_INVALID_ARG;
345 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
350 SysTryReturnResult(NID_LCL, otherInstance.__pCalendar, r, "Invalid argument is used. otherCalendar instance is invalid");
352 return __pCalendar->Before(*(otherInstance.__pCalendar), before);
356 _CalendarImpl::Equals(const _CalendarImpl& otherInstance) const
358 if ((__pCalendar != null) && (otherInstance.__pCalendar != null))
360 return __pCalendar->Equals(*(otherInstance.__pCalendar));
362 return (__pCalendar == otherInstance.__pCalendar);
366 _CalendarImpl::GetHashCode(void) const
368 Integer intValues = IsLenient() + GetFirstDayOfWeek() + GetMinDaysInFirstWeek();
369 int hashCode = intValues.GetHashCode();
371 long long myTicks = 0;
372 GetTimeInMillisec(myTicks);
373 hashCode = (hashCode << 5) - hashCode + LongLong(myTicks).GetHashCode()+__timezone.GetHashCode();
379 _CalendarImpl::GetType(void) const
385 _CalendarImpl::GetTimeFieldImpl(TimeField field) const
387 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
388 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
389 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
391 return __pCalendar->GetTimeField(field);
395 _CalendarImpl::GetTimeInMillisecImpl(long long& millisec) const
397 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
399 long long tempMillisec;
401 r = __pCalendar->GetTimeInMillisec(tempMillisec);
402 SysTryReturnResult(NID_LCL, r == E_SUCCESS, r, "Unable to get time in milli sec");
403 millisec = tempMillisec + __timezone.GetRawOffset() * ONE_MINUTE_IN_MILLISEC;
408 _CalendarImpl::GetTimeImpl(void) const
410 int year = __pCalendar->GetTimeField(TIME_FIELD_YEAR);
411 int month = __pCalendar->GetTimeField(TIME_FIELD_MONTH);
412 int date = __pCalendar->GetTimeField(TIME_FIELD_DAY_OF_MONTH);
414 int hour = __pCalendar->GetTimeField(TIME_FIELD_HOUR_OF_DAY);
415 int minute = __pCalendar->GetTimeField(TIME_FIELD_MINUTE);
416 int second = __pCalendar->GetTimeField(TIME_FIELD_SECOND);
417 int millisecond = __pCalendar->GetTimeField(TIME_FIELD_MILLISECOND);
420 result r = dateTime.SetValue(year, month, date, hour, minute, second, millisecond);
421 SysTryReturn(NID_LCL, r == E_SUCCESS, DateTime(), r, "[%s] Unable to set time in DateTime object", GetErrorMessage(r));
427 _CalendarImpl::GetMinTimeField(TimeField field) const
429 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
430 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
431 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
433 return __pCalendar->GetMinTimeField(field);
437 _CalendarImpl::GetActualMinTimeFieldImpl(TimeField field) const
439 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
440 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
441 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
443 return __pCalendar->GetActualMinTimeField(field);
447 _CalendarImpl::GetGreatestMinTimeField(TimeField field) const
449 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
450 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
451 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
453 return __pCalendar->GetGreatestMinTimeField(field);
457 _CalendarImpl::GetLeastMaxTimeField(TimeField field) const
459 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
460 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
461 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
463 return __pCalendar->GetLeastMaxTimeField(field);
467 _CalendarImpl::GetActualMaxTimeFieldImpl(TimeField field) const
469 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
470 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
471 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
473 return __pCalendar->GetActualMaxTimeField(field);
477 _CalendarImpl::GetMaxTimeField(TimeField field) const
479 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
480 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
481 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
483 return __pCalendar->GetMaxTimeField(field);
487 _CalendarImpl::GetFirstDayOfWeekImpl(void) const
489 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
490 return __pCalendar->GetFirstDayOfWeek();
494 _CalendarImpl::GetMinDaysInFirstWeekImpl(void) const
496 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
497 return __pCalendar->GetMinDaysInFirstWeek();
501 _CalendarImpl::IsInDst(bool& isInDst) const
503 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
504 return __pCalendar->IsInDst(isInDst);
508 _CalendarImpl::IsLenientImpl(void) const
510 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
511 return __pCalendar->IsLenient();
515 _CalendarImpl::IsSetImpl(TimeField field) const
517 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
518 return __pCalendar->IsSet(field);
522 _CalendarImpl::GetTimeZoneImpl(void) const
528 _CalendarImpl::IsLeapYear(int year) const
530 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
531 return __pCalendar->IsLeapYear(year);
535 _CalendarImpl::SetGregorianChange(long long change)
537 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
538 return __pCalendar->SetGregorianChange(change);
542 _CalendarImpl::GetGregorianChange(void) const
544 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
545 return __pCalendar->GetGregorianChange();
549 _CalendarImpl::SetJulianDay(int julianDay)
551 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
552 return __pCalendar->SetJulianDay(julianDay);
556 _CalendarImpl::GetJulianDay(void) const
558 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
559 return __pCalendar->GetJulianDay();
563 _CalendarImpl::ValidateTimeField(TimeField field) const
565 if (field < 0 || field >= TIME_FIELD_FIELD_COUNT)
573 _CalendarImpl::ValidateTimeFieldValue(TimeField field, int value) const
575 if (IsLenientImpl() == false)
577 if ((value < GetMinTimeField(field)) || (value > GetMaxTimeField(field)))
587 _CalendarImpl::ValidateDaysOfWeek(DayOfWeek dayOfWeek) const
589 if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY)
596 // added for backward compatibility
598 _CalendarImpl::RollWithSingleUnit(TimeField field, bool up)
600 return E_UNSUPPORTED_OPERATION;
603 // added for backward compatibility
605 _CalendarImpl::ComputeTimeFields(void)
607 return E_UNSUPPORTED_OPERATION;
610 // added for backward compatibility
612 _CalendarImpl::ComputeTime(void)
614 return E_UNSUPPORTED_OPERATION;
617 // added for backward compatibility
619 _CalendarImpl::GetMonthLength(int extendedYear, int month) const
621 SetLastResult(E_UNSUPPORTED_OPERATION);
625 // added for backward compatibility
627 _CalendarImpl::HandleGetLimit(TimeField field, CalendarLimitType limitType) const
629 SetLastResult(E_UNSUPPORTED_OPERATION);
633 const _IcuCalendarImpl*
634 _CalendarImpl::GetImpl(const Calendar& calendar)
636 if (calendar._pCalendarImpl)
638 return calendar._pCalendarImpl->__pCalendar;