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 _CalendarImpl::_CalendarImpl()
42 : __type(CALENDAR_GREGORIAN)
43 , __locale(LANGUAGE_INVALID, COUNTRY_INVALID)
49 _CalendarImpl::~_CalendarImpl()
57 _CalendarImpl::CreateCalendarInstanceN(CalendarType calendarType)
59 return CreateInstanceN(TimeZone::GetGmtTimeZone(), calendarType);
63 _CalendarImpl::CreateCalendarInstanceN(const TimeZone& timeZone, CalendarType calendarType)
65 return CreateInstanceN(timeZone, _LocaleManagerImpl::GetSystemLocale(), calendarType);
69 _CalendarImpl::CreateCalendarInstanceN(const Locale& locale, CalendarType calendarType)
71 // Create calendar using system time zone and given locale and calendar type
72 return CreateInstanceN(TimeZone::GetGmtTimeZone(), locale, calendarType);
76 _CalendarImpl::CreateCalendarInstanceN(const TimeZone& timeZone, const Locale& locale, CalendarType calendarType)
82 case CALENDAR_GREGORIAN:
84 std::unique_ptr< GregorianCalendar > pGregCalendar(new (std::nothrow) GregorianCalendar);
85 SysTryReturn(NID_LCL, pGregCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
87 r = pGregCalendar->Construct(timeZone, locale);
88 SysTryReturn(NID_LCL, !IsFailed(r), null, r, "[%s] Unable to construct calendar", GetErrorMessage(r));
90 return pGregCalendar.release();
97 std::unique_ptr< _CalendarImpl > pCalendar(new (std::nothrow) _CalendarImpl);
98 SysTryReturn(NID_LCL, pCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
100 r = pCalendar->Construct(timeZone, locale, calendarType);
102 SysTryReturn(NID_LCL, !IsFailed(r), null, r, "[%s] Unable to construct calendar", GetErrorMessage(r));
103 return pCalendar.release();
107 _CalendarImpl::CloneN(void) const
109 std::unique_ptr< _CalendarImpl > pCalendar(new (std::nothrow) _CalendarImpl());
110 SysTryReturn(NID_LCL, pCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
112 if (__pCalendar != null)
114 pCalendar->__pCalendar = __pCalendar->CloneN();
115 if (pCalendar->__pCalendar != null)
117 pCalendar->__type = __type;
118 pCalendar->__locale = __locale;
119 pCalendar->__timezone = __timezone;
121 pCalendar->_pCalendarImpl = pCalendar.get();
125 return pCalendar.release();
129 _CalendarImpl::Construct(CalendarType calendarType)
131 Locale defaultLocale = _LocaleManagerImpl::GetSystemLocale();
132 return Construct( TimeZone::GetGmtTimeZone(), defaultLocale, calendarType);
136 _CalendarImpl::Construct(const TimeZone& timezone, CalendarType calendarType)
138 Locale defaultLocale = _LocaleManagerImpl::GetSystemLocale();
139 return Construct(timezone, defaultLocale, calendarType);
143 _CalendarImpl::Construct(const Locale& locale, CalendarType calendarType)
145 TimeZone defaultTimeZone = TimeZone::GetGmtTimeZone();
146 return Construct(defaultTimeZone, locale, calendarType);
150 _CalendarImpl::Construct(const TimeZone& timeZone, const Locale& locale, CalendarType calendarType)
152 // Object is not allowed to construct twice
153 SysAssertf(__pCalendar == null,
154 "Already constructed! Calling Construct() twice or more on a same instance is not allowed for this class");
156 SysTryReturnResult(NID_LCL, _LocaleImpl::IsSupported(locale), E_INVALID_ARG, "Given locale is not supported");
158 std::unique_ptr< _IcuCalendarImpl > pCalendar(new (std::nothrow) _IcuCalendarImpl);
159 SysTryReturnResult(NID_LCL, pCalendar != null, E_OUT_OF_MEMORY, "Memory allocation failed");
161 result r = pCalendar->Construct(timeZone, locale, calendarType);
164 __pCalendar = pCalendar.release();
165 __type = calendarType;
167 __timezone = timeZone;
169 _pCalendarImpl = this;
177 _CalendarImpl::Construct(const Calendar& otherCalendar)
179 // Object is not allowed to construct twice
180 SysAssertf(__pCalendar == null,
181 "Already constructed! Calling Construct() twice or more on a same instance is not allowed for this class");
184 const _CalendarImpl* pOtherCalendar = dynamic_cast< const _CalendarImpl* >(&otherCalendar);
185 if ((pOtherCalendar != null) && (pOtherCalendar->__pCalendar != null))
189 __pCalendar = pOtherCalendar->__pCalendar->CloneN();
190 if (__pCalendar != null)
192 __type = pOtherCalendar->__type;
193 __locale = pOtherCalendar->__locale;
194 __timezone = pOtherCalendar->__timezone;
196 _pCalendarImpl = pOtherCalendar->_pCalendarImpl;
205 _CalendarImpl::SetTimeFieldImpl(TimeField field, int value)
207 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
208 SysTryReturnResult(NID_LCL, ValidateTimeField(field),
209 E_INVALID_ARG, "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
210 SysTryReturnResult(NID_LCL, ValidateTimeFieldValue(field, value), E_OUT_OF_RANGE, "value(%d) is out of range.", value);
212 return __pCalendar->SetTimeField(field, value);
216 _CalendarImpl::SetTimeInMillisecImpl(long long millisec)
218 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
219 return __pCalendar->SetTimeInMillisec(millisec - __timezone.GetRawOffset() * ONE_MINUTE_IN_MILLISEC);
223 _CalendarImpl::SetTimeImpl(const DateTime& dateTime)
225 return SetTimeImpl(dateTime.GetYear(), dateTime.GetMonth(), dateTime.GetDay(),
226 dateTime.GetHour(), dateTime.GetMinute(), dateTime.GetSecond(), dateTime.GetMillisecond());
230 _CalendarImpl::SetTimeImpl(int year, int month, int day, int hour, int minute, int second, int millisecond)
232 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
233 return __pCalendar->SetTime(year, month, day, hour, minute, second, millisecond);
237 _CalendarImpl::SetFirstDayOfWeekImpl(DayOfWeek dayOfWeek)
239 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
240 SysTryReturnResult(NID_LCL, ValidateDaysOfWeek(dayOfWeek), E_INVALID_ARG, "Invalid argument is used. Unknown day of week");
242 return __pCalendar->SetFirstDayOfWeek(dayOfWeek);
246 _CalendarImpl::SetLenientImpl(bool lenient)
248 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
249 return __pCalendar->SetLenient(lenient);
253 _CalendarImpl::SetMinDaysInFirstWeekImpl(short value)
255 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
256 return __pCalendar->SetMinDaysInFirstWeek(value);
260 _CalendarImpl::SetTimeZoneImpl(const TimeZone& timeZone)
262 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
264 _timeZone = timeZone;
265 __timezone = timeZone;
266 return __pCalendar->SetTimeZone(__timezone);
270 _CalendarImpl::ClearImpl(void)
272 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
273 return __pCalendar->Clear();
277 _CalendarImpl::ClearImpl(TimeField field)
279 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
280 SysTryReturnResult(NID_LCL, ValidateTimeField(field), E_INVALID_ARG,
281 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
283 return __pCalendar->Clear(field);
287 _CalendarImpl::AddTimeField(TimeField field, int amount)
289 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
291 result r = E_INVALID_ARG;
293 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
298 SysTryReturnResult(NID_LCL, ValidateTimeField(field), r,
299 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
301 return __pCalendar->AddTimeField(field, amount);
305 _CalendarImpl::RollImpl(TimeField field, int amount)
307 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
308 result r = E_INVALID_ARG;
309 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
314 SysTryReturnResult(NID_LCL, ValidateTimeField(field), r,
315 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
317 return __pCalendar->Roll(field, amount);
321 _CalendarImpl::AfterImpl(const _CalendarImpl& otherInstance, bool& after)
323 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
325 result r = E_INVALID_ARG;
326 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
331 SysTryReturnResult(NID_LCL, otherInstance.__pCalendar, r, "Invalid argument is used. otherCalendar instance is invalid");
333 return __pCalendar->After(*(otherInstance.__pCalendar), after);
337 _CalendarImpl::BeforeImpl(const _CalendarImpl& otherInstance, bool& before)
339 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
341 result r = E_INVALID_ARG;
342 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
347 SysTryReturnResult(NID_LCL, otherInstance.__pCalendar, r, "Invalid argument is used. otherCalendar instance is invalid");
349 return __pCalendar->Before(*(otherInstance.__pCalendar), before);
353 _CalendarImpl::EqualsImpl(const _CalendarImpl& otherInstance) const
355 if ((__pCalendar != null) && (otherInstance.__pCalendar != null))
357 return __pCalendar->Equals(*(otherInstance.__pCalendar));
359 return (__pCalendar == otherInstance.__pCalendar);
363 _CalendarImpl::GetHashCodeImpl(void) const
365 Integer intValues = IsLenient() + GetFirstDayOfWeek() + GetMinDaysInFirstWeek();
366 int hashCode = intValues.GetHashCode();
368 long long myTicks = 0;
369 GetTimeInMillisec(myTicks);
370 hashCode = (hashCode << 5) - hashCode + LongLong(myTicks).GetHashCode()+__timezone.GetHashCode();
376 _CalendarImpl::GetType(void) const
382 _CalendarImpl::GetTimeFieldImpl(TimeField field) const
384 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
385 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
386 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
388 return __pCalendar->GetTimeField(field);
392 _CalendarImpl::GetTimeInMillisecImpl(long long& millisec) const
394 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
396 long long tempMillisec;
398 r = __pCalendar->GetTimeInMillisec(tempMillisec);
399 SysTryReturnResult(NID_LCL, r == E_SUCCESS, r, "Unable to get time in milli sec");
400 millisec = tempMillisec + __timezone.GetRawOffset() * ONE_MINUTE_IN_MILLISEC;
405 _CalendarImpl::GetTimeImpl(void) const
407 int year = __pCalendar->GetTimeField(TIME_FIELD_YEAR);
408 int month = __pCalendar->GetTimeField(TIME_FIELD_MONTH);
409 int date = __pCalendar->GetTimeField(TIME_FIELD_DAY_OF_MONTH);
411 int hour = __pCalendar->GetTimeField(TIME_FIELD_HOUR_OF_DAY);
412 int minute = __pCalendar->GetTimeField(TIME_FIELD_MINUTE);
413 int second = __pCalendar->GetTimeField(TIME_FIELD_SECOND);
414 int millisecond = __pCalendar->GetTimeField(TIME_FIELD_MILLISECOND);
417 result r = dateTime.SetValue(year, month, date, hour, minute, second, millisecond);
418 SysTryReturn(NID_LCL, r == E_SUCCESS, DateTime(), r, "[%s] Unable to set time in DateTime object", GetErrorMessage(r));
424 _CalendarImpl::GetMinTimeFieldImpl(TimeField field) const
426 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
427 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
428 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
430 return __pCalendar->GetMinTimeField(field);
434 _CalendarImpl::GetActualMinTimeFieldImpl(TimeField field) const
436 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
437 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
438 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
440 return __pCalendar->GetActualMinTimeField(field);
444 _CalendarImpl::GetGreatestMinTimeFieldImpl(TimeField field) const
446 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
447 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
448 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
450 return __pCalendar->GetGreatestMinTimeField(field);
454 _CalendarImpl::GetLeastMaxTimeFieldImpl(TimeField field) const
456 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
457 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
458 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
460 return __pCalendar->GetLeastMaxTimeField(field);
464 _CalendarImpl::GetActualMaxTimeFieldImpl(TimeField field) const
466 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
467 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
468 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
470 return __pCalendar->GetActualMaxTimeField(field);
474 _CalendarImpl::GetMaxTimeFieldImpl(TimeField field) const
476 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
477 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
478 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
480 return __pCalendar->GetMaxTimeField(field);
484 _CalendarImpl::GetFirstDayOfWeekImpl(void) const
486 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
487 return __pCalendar->GetFirstDayOfWeek();
491 _CalendarImpl::GetMinDaysInFirstWeekImpl(void) const
493 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
494 return __pCalendar->GetMinDaysInFirstWeek();
498 _CalendarImpl::IsInDst(bool& isInDst) const
500 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
501 return __pCalendar->IsInDst(isInDst);
505 _CalendarImpl::IsLenientImpl(void) const
507 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
508 return __pCalendar->IsLenient();
512 _CalendarImpl::IsSetImpl(TimeField field) const
514 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
515 return __pCalendar->IsSet(field);
519 _CalendarImpl::GetTimeZoneImpl(void) const
525 _CalendarImpl::IsLeapYear(int year) const
527 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
528 return __pCalendar->IsLeapYear(year);
532 _CalendarImpl::SetGregorianChange(long long change)
534 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
535 return __pCalendar->SetGregorianChange(change);
539 _CalendarImpl::GetGregorianChange(void) const
541 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
542 return __pCalendar->GetGregorianChange();
546 _CalendarImpl::SetJulianDay(int julianDay)
548 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
549 return __pCalendar->SetJulianDay(julianDay);
553 _CalendarImpl::GetJulianDay(void) const
555 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
556 return __pCalendar->GetJulianDay();
560 _CalendarImpl::ValidateTimeField(TimeField field) const
562 if (field < 0 || field >= TIME_FIELD_FIELD_COUNT)
570 _CalendarImpl::ValidateTimeFieldValue(TimeField field, int value) const
572 if (IsLenientImpl() == false)
574 if ((value < GetMinTimeField(field)) || (value > GetMaxTimeField(field)))
584 _CalendarImpl::ValidateDaysOfWeek(DayOfWeek dayOfWeek) const
586 if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY)
593 // added for backward compatibility
595 _CalendarImpl::RollWithSingleUnit(TimeField field, bool up)
597 return E_UNSUPPORTED_OPERATION;
600 // added for backward compatibility
602 _CalendarImpl::ComputeTimeFields(void)
604 return E_UNSUPPORTED_OPERATION;
607 // added for backward compatibility
609 _CalendarImpl::ComputeTime(void)
611 return E_UNSUPPORTED_OPERATION;
614 // added for backward compatibility
616 _CalendarImpl::GetMonthLength(int extendedYear, int month) const
618 SetLastResult(E_UNSUPPORTED_OPERATION);
622 // added for backward compatibility
624 _CalendarImpl::HandleGetLimit(TimeField field, CalendarLimitType limitType) const
626 SetLastResult(E_UNSUPPORTED_OPERATION);
630 const _IcuCalendarImpl*
631 _CalendarImpl::GetImpl(const Calendar& calendar)
633 if (calendar._pCalendarImpl)
635 return calendar._pCalendarImpl->__pCalendar;