2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FLcl_CalendarImpl.cpp
19 * @brief This is the implementation file for _CalendarImpl class.
23 #include <unique_ptr.h>
25 #include <FBaseDateTime.h>
26 #include <FBaseSysLog.h>
27 #include <FApp_AppInfo.h>
28 #include <FLclGregorianCalendar.h>
30 #include "FLcl_CalendarImpl.h"
31 #include "FLcl_IcuCalendarImpl.h"
32 #include "FLcl_LocaleData.h"
33 #include "FLcl_LocaleImpl.h"
34 #include "FLcl_LocaleManagerImpl.h"
36 using namespace Tizen::Base;
38 namespace Tizen { namespace Locales
41 static const int ONE_MINUTE_IN_MILLISEC = 60000;
43 _CalendarImpl::_CalendarImpl()
44 : __type(CALENDAR_GREGORIAN)
45 , __locale(LANGUAGE_INVALID, COUNTRY_INVALID)
51 _CalendarImpl::~_CalendarImpl()
59 _CalendarImpl::CreateCalendarInstanceN(CalendarType calendarType)
61 return CreateInstanceN(TimeZone::GetGmtTimeZone(), calendarType);
65 _CalendarImpl::CreateCalendarInstanceN(const TimeZone& timeZone, CalendarType calendarType)
67 return CreateInstanceN(timeZone, _LocaleManagerImpl::GetSystemLocale(), calendarType);
71 _CalendarImpl::CreateCalendarInstanceN(const Locale& locale, CalendarType calendarType)
73 // Create calendar using system time zone and given locale and calendar type
74 return CreateInstanceN(TimeZone::GetGmtTimeZone(), locale, calendarType);
78 _CalendarImpl::CreateCalendarInstanceN(const TimeZone& timeZone, const Locale& locale, CalendarType calendarType)
84 case CALENDAR_GREGORIAN:
86 std::unique_ptr< GregorianCalendar > pGregCalendar(new (std::nothrow) GregorianCalendar);
87 SysTryReturn(NID_LCL, pGregCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
89 r = pGregCalendar->Construct(timeZone, locale);
90 SysTryReturn(NID_LCL, !IsFailed(r), null, r, "[%s] Unable to construct calendar", GetErrorMessage(r));
92 return pGregCalendar.release();
99 std::unique_ptr< _CalendarImpl > pCalendar(new (std::nothrow) _CalendarImpl);
100 SysTryReturn(NID_LCL, pCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
102 r = pCalendar->Construct(timeZone, locale, calendarType);
104 SysTryReturn(NID_LCL, !IsFailed(r), null, r, "[%s] Unable to construct calendar", GetErrorMessage(r));
105 return pCalendar.release();
109 _CalendarImpl::CloneN(void) const
111 std::unique_ptr< _CalendarImpl > pCalendar(new (std::nothrow) _CalendarImpl());
112 SysTryReturn(NID_LCL, pCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
114 if (__pCalendar != null)
116 pCalendar->__pCalendar = __pCalendar->CloneN();
117 if (pCalendar->__pCalendar != null)
119 pCalendar->__type = __type;
120 pCalendar->__locale = __locale;
121 pCalendar->__timezone = __timezone;
123 pCalendar->_pCalendarImpl = pCalendar.get();
127 return pCalendar.release();
131 _CalendarImpl::Construct(CalendarType calendarType)
133 Locale defaultLocale = _LocaleManagerImpl::GetSystemLocale();
134 return Construct( TimeZone::GetGmtTimeZone(), defaultLocale, calendarType);
138 _CalendarImpl::Construct(const TimeZone& timezone, CalendarType calendarType)
140 Locale defaultLocale = _LocaleManagerImpl::GetSystemLocale();
141 return Construct(timezone, defaultLocale, calendarType);
145 _CalendarImpl::Construct(const Locale& locale, CalendarType calendarType)
147 TimeZone defaultTimeZone = TimeZone::GetGmtTimeZone();
148 return Construct(defaultTimeZone, locale, calendarType);
152 _CalendarImpl::Construct(const TimeZone& timeZone, const Locale& locale, CalendarType calendarType)
154 // Object is not allowed to construct twice
155 SysAssertf(__pCalendar == null,
156 "Already constructed! Calling Construct() twice or more on a same instance is not allowed for this class");
158 SysTryReturnResult(NID_LCL, _LocaleImpl::IsSupported(locale), E_INVALID_ARG, "Given locale is not supported");
160 std::unique_ptr< _IcuCalendarImpl > pCalendar(new (std::nothrow) _IcuCalendarImpl);
161 SysTryReturnResult(NID_LCL, pCalendar != null, E_OUT_OF_MEMORY, "Memory allocation failed");
163 result r = pCalendar->Construct(timeZone, locale, calendarType);
166 __pCalendar = pCalendar.release();
167 __type = calendarType;
169 __timezone = timeZone;
171 _pCalendarImpl = this;
179 _CalendarImpl::Construct(const Calendar& otherCalendar)
181 // Object is not allowed to construct twice
182 SysAssertf(__pCalendar == null,
183 "Already constructed! Calling Construct() twice or more on a same instance is not allowed for this class");
186 const _CalendarImpl* pOtherCalendar = dynamic_cast< const _CalendarImpl* >(&otherCalendar);
187 if ((pOtherCalendar != null) && (pOtherCalendar->__pCalendar != null))
191 __pCalendar = pOtherCalendar->__pCalendar->CloneN();
192 if (__pCalendar != null)
194 __type = pOtherCalendar->__type;
195 __locale = pOtherCalendar->__locale;
196 __timezone = pOtherCalendar->__timezone;
198 _pCalendarImpl = pOtherCalendar->_pCalendarImpl;
207 _CalendarImpl::SetTimeFieldImpl(TimeField field, int value)
209 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
210 SysTryReturnResult(NID_LCL, ValidateTimeField(field),
211 E_INVALID_ARG, "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
212 SysTryReturnResult(NID_LCL, ValidateTimeFieldValue(field, value), E_OUT_OF_RANGE, "value(%d) is out of range.", value);
214 return __pCalendar->SetTimeField(field, value);
218 _CalendarImpl::SetTimeInMillisecImpl(long long millisec)
220 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
221 return __pCalendar->SetTimeInMillisec(millisec - __timezone.GetRawOffset() * ONE_MINUTE_IN_MILLISEC);
225 _CalendarImpl::SetTimeImpl(const DateTime& dateTime)
227 return SetTimeImpl(dateTime.GetYear(), dateTime.GetMonth(), dateTime.GetDay(),
228 dateTime.GetHour(), dateTime.GetMinute(), dateTime.GetSecond(), dateTime.GetMillisecond());
232 _CalendarImpl::SetTimeImpl(int year, int month, int day, int hour, int minute, int second, int millisecond)
234 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
235 return __pCalendar->SetTime(year, month, day, hour, minute, second, millisecond);
239 _CalendarImpl::SetFirstDayOfWeekImpl(DayOfWeek dayOfWeek)
241 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
242 SysTryReturnResult(NID_LCL, ValidateDaysOfWeek(dayOfWeek), E_INVALID_ARG, "Invalid argument is used. Unknown day of week");
244 return __pCalendar->SetFirstDayOfWeek(dayOfWeek);
248 _CalendarImpl::SetLenientImpl(bool lenient)
250 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
251 return __pCalendar->SetLenient(lenient);
255 _CalendarImpl::SetMinDaysInFirstWeekImpl(short value)
257 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
258 return __pCalendar->SetMinDaysInFirstWeek(value);
262 _CalendarImpl::SetTimeZoneImpl(const TimeZone& timeZone)
264 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
266 _timeZone = timeZone;
267 __timezone = timeZone;
268 return __pCalendar->SetTimeZone(__timezone);
272 _CalendarImpl::ClearImpl(void)
274 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
275 return __pCalendar->Clear();
279 _CalendarImpl::ClearImpl(TimeField field)
281 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
282 SysTryReturnResult(NID_LCL, ValidateTimeField(field), E_INVALID_ARG,
283 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
285 return __pCalendar->Clear(field);
289 _CalendarImpl::AddTimeField(TimeField field, int amount)
291 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
293 result r = E_INVALID_ARG;
295 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
300 SysTryReturnResult(NID_LCL, ValidateTimeField(field), r,
301 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
303 return __pCalendar->AddTimeField(field, amount);
307 _CalendarImpl::RollImpl(TimeField field, int amount)
309 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
310 result r = E_INVALID_ARG;
311 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
316 SysTryReturnResult(NID_LCL, ValidateTimeField(field), r,
317 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
319 return __pCalendar->Roll(field, amount);
323 _CalendarImpl::AfterImpl(const _CalendarImpl& otherInstance, bool& after)
325 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
327 result r = E_INVALID_ARG;
328 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
333 SysTryReturnResult(NID_LCL, otherInstance.__pCalendar, r, "Invalid argument is used. otherCalendar instance is invalid");
335 return __pCalendar->After(*(otherInstance.__pCalendar), after);
339 _CalendarImpl::BeforeImpl(const _CalendarImpl& otherInstance, bool& before)
341 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
343 result r = E_INVALID_ARG;
344 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
349 SysTryReturnResult(NID_LCL, otherInstance.__pCalendar, r, "Invalid argument is used. otherCalendar instance is invalid");
351 return __pCalendar->Before(*(otherInstance.__pCalendar), before);
355 _CalendarImpl::EqualsImpl(const _CalendarImpl& otherInstance) const
357 if ((__pCalendar != null) && (otherInstance.__pCalendar != null))
359 return __pCalendar->Equals(*(otherInstance.__pCalendar));
361 return (__pCalendar == otherInstance.__pCalendar);
365 _CalendarImpl::GetHashCodeImpl(void) const
367 Integer intValues = IsLenient() + GetFirstDayOfWeek() + GetMinDaysInFirstWeek();
368 int hashCode = intValues.GetHashCode();
370 long long myTicks = 0;
371 GetTimeInMillisec(myTicks);
372 hashCode = (hashCode << 5) - hashCode + LongLong(myTicks).GetHashCode()+__timezone.GetHashCode();
378 _CalendarImpl::GetType(void) const
384 _CalendarImpl::GetTimeFieldImpl(TimeField field) const
386 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
387 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
388 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
390 return __pCalendar->GetTimeField(field);
394 _CalendarImpl::GetTimeInMillisecImpl(long long& millisec) const
396 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
398 long long tempMillisec;
400 r = __pCalendar->GetTimeInMillisec(tempMillisec);
401 SysTryReturnResult(NID_LCL, r == E_SUCCESS, r, "Unable to get time in milli sec");
402 millisec = tempMillisec + __timezone.GetRawOffset() * ONE_MINUTE_IN_MILLISEC;
407 _CalendarImpl::GetTimeImpl(void) const
409 int year = __pCalendar->GetTimeField(TIME_FIELD_YEAR);
410 int month = __pCalendar->GetTimeField(TIME_FIELD_MONTH);
411 int date = __pCalendar->GetTimeField(TIME_FIELD_DAY_OF_MONTH);
413 int hour = __pCalendar->GetTimeField(TIME_FIELD_HOUR_OF_DAY);
414 int minute = __pCalendar->GetTimeField(TIME_FIELD_MINUTE);
415 int second = __pCalendar->GetTimeField(TIME_FIELD_SECOND);
416 int millisecond = __pCalendar->GetTimeField(TIME_FIELD_MILLISECOND);
419 result r = dateTime.SetValue(year, month, date, hour, minute, second, millisecond);
420 SysTryReturn(NID_LCL, r == E_SUCCESS, DateTime(), r, "[%s] Unable to set time in DateTime object", GetErrorMessage(r));
426 _CalendarImpl::GetMinTimeFieldImpl(TimeField field) const
428 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
429 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
430 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
432 return __pCalendar->GetMinTimeField(field);
436 _CalendarImpl::GetActualMinTimeFieldImpl(TimeField field) const
438 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
439 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
440 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
442 return __pCalendar->GetActualMinTimeField(field);
446 _CalendarImpl::GetGreatestMinTimeFieldImpl(TimeField field) const
448 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
449 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
450 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
452 return __pCalendar->GetGreatestMinTimeField(field);
456 _CalendarImpl::GetLeastMaxTimeFieldImpl(TimeField field) const
458 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
459 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
460 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
462 return __pCalendar->GetLeastMaxTimeField(field);
466 _CalendarImpl::GetActualMaxTimeFieldImpl(TimeField field) const
468 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
469 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
470 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
472 return __pCalendar->GetActualMaxTimeField(field);
476 _CalendarImpl::GetMaxTimeFieldImpl(TimeField field) const
478 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
479 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
480 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
482 return __pCalendar->GetMaxTimeField(field);
486 _CalendarImpl::GetFirstDayOfWeekImpl(void) const
488 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
489 return __pCalendar->GetFirstDayOfWeek();
493 _CalendarImpl::GetMinDaysInFirstWeekImpl(void) const
495 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
496 return __pCalendar->GetMinDaysInFirstWeek();
500 _CalendarImpl::IsInDst(bool& isInDst) const
502 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
503 return __pCalendar->IsInDst(isInDst);
507 _CalendarImpl::IsLenientImpl(void) const
509 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
510 return __pCalendar->IsLenient();
514 _CalendarImpl::IsSetImpl(TimeField field) const
516 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
517 return __pCalendar->IsSet(field);
521 _CalendarImpl::GetTimeZoneImpl(void) const
527 _CalendarImpl::IsLeapYear(int year) const
529 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
530 return __pCalendar->IsLeapYear(year);
534 _CalendarImpl::SetGregorianChange(long long change)
536 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
537 return __pCalendar->SetGregorianChange(change);
541 _CalendarImpl::GetGregorianChange(void) const
543 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
544 return __pCalendar->GetGregorianChange();
548 _CalendarImpl::SetJulianDay(int julianDay)
550 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
551 return __pCalendar->SetJulianDay(julianDay);
555 _CalendarImpl::GetJulianDay(void) const
557 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
558 return __pCalendar->GetJulianDay();
562 _CalendarImpl::ValidateTimeField(TimeField field) const
564 if (field < 0 || field >= TIME_FIELD_FIELD_COUNT)
572 _CalendarImpl::ValidateTimeFieldValue(TimeField field, int value) const
574 if (IsLenientImpl() == false)
576 if ((value < GetMinTimeField(field)) || (value > GetMaxTimeField(field)))
586 _CalendarImpl::ValidateDaysOfWeek(DayOfWeek dayOfWeek) const
588 if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY)
595 // added for backward compatibility
597 _CalendarImpl::RollWithSingleUnit(TimeField field, bool up)
599 return E_UNSUPPORTED_OPERATION;
602 // added for backward compatibility
604 _CalendarImpl::ComputeTimeFields(void)
606 return E_UNSUPPORTED_OPERATION;
609 // added for backward compatibility
611 _CalendarImpl::ComputeTime(void)
613 return E_UNSUPPORTED_OPERATION;
616 // added for backward compatibility
618 _CalendarImpl::GetMonthLength(int extendedYear, int month) const
620 SetLastResult(E_UNSUPPORTED_OPERATION);
624 // added for backward compatibility
626 _CalendarImpl::HandleGetLimit(TimeField field, CalendarLimitType limitType) const
628 SetLastResult(E_UNSUPPORTED_OPERATION);
632 const _IcuCalendarImpl*
633 _CalendarImpl::GetImpl(const Calendar& calendar)
635 if (calendar._pCalendarImpl)
637 return calendar._pCalendarImpl->__pCalendar;