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"
35 using namespace Tizen::Base;
37 namespace Tizen { namespace Locales
40 static const int ONE_MINUTE_IN_MILLISEC = 60000;
42 _CalendarImpl::_CalendarImpl()
43 : __type(CALENDAR_GREGORIAN)
44 , __locale(LANGUAGE_INVALID, COUNTRY_INVALID)
50 _CalendarImpl::~_CalendarImpl()
58 _CalendarImpl::CreateCalendarInstanceN(CalendarType calendarType)
60 return CreateInstanceN(TimeZone::GetGmtTimeZone(), calendarType);
64 _CalendarImpl::CreateCalendarInstanceN(const TimeZone& timeZone, CalendarType calendarType)
66 return CreateInstanceN(timeZone, _LocaleData::GetOspSystemLocale(), calendarType);
70 _CalendarImpl::CreateCalendarInstanceN(const Locale& locale, CalendarType calendarType)
72 // Create calendar using system time zone and given locale and calendar type
73 return CreateInstanceN(TimeZone::GetGmtTimeZone(), locale, calendarType);
77 _CalendarImpl::CreateCalendarInstanceN(const TimeZone& timeZone, const Locale& locale, CalendarType calendarType)
83 case CALENDAR_GREGORIAN:
85 std::unique_ptr< GregorianCalendar > pGregCalendar(new (std::nothrow) GregorianCalendar);
86 SysTryReturn(NID_LCL, pGregCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
88 r = pGregCalendar->Construct(timeZone, locale);
89 SysTryReturn(NID_LCL, !IsFailed(r), null, r, "[%s] Unable to construct calendar", GetErrorMessage(r));
91 return pGregCalendar.release();
98 std::unique_ptr< _CalendarImpl > pCalendar(new (std::nothrow) _CalendarImpl);
99 SysTryReturn(NID_LCL, pCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
101 r = pCalendar->Construct(timeZone, locale, calendarType);
103 SysTryReturn(NID_LCL, !IsFailed(r), null, r, "[%s] Unable to construct calendar", GetErrorMessage(r));
104 return pCalendar.release();
108 _CalendarImpl::CloneN(void) const
110 std::unique_ptr< _CalendarImpl > pCalendar(new (std::nothrow) _CalendarImpl());
111 SysTryReturn(NID_LCL, pCalendar != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
113 if (__pCalendar != null)
115 pCalendar->__pCalendar = __pCalendar->CloneN();
116 if (pCalendar->__pCalendar != null)
118 pCalendar->__type = __type;
119 pCalendar->__locale = __locale;
120 pCalendar->__timezone = __timezone;
122 pCalendar->_pCalendarImpl = pCalendar.get();
126 return pCalendar.release();
130 _CalendarImpl::Construct(CalendarType calendarType)
132 Locale defaultLocale = _LocaleData::GetOspSystemLocale();
133 return Construct( TimeZone::GetGmtTimeZone(), defaultLocale, calendarType);
137 _CalendarImpl::Construct(const TimeZone& timezone, CalendarType calendarType)
139 Locale defaultLocale = _LocaleData::GetOspSystemLocale();
140 return Construct(timezone, defaultLocale, calendarType);
144 _CalendarImpl::Construct(const Locale& locale, CalendarType calendarType)
146 TimeZone defaultTimeZone = TimeZone::GetGmtTimeZone();
147 return Construct(defaultTimeZone, locale, calendarType);
151 _CalendarImpl::Construct(const TimeZone& timeZone, const Locale& locale, CalendarType calendarType)
153 // Object is not allowed to construct twice
154 SysAssertf(__pCalendar == null,
155 "Already constructed! Calling Construct() twice or more on a same instance is not allowed for this class");
157 SysTryReturnResult(NID_LCL, locale.GetLanguageCode() != LANGUAGE_INVALID,
158 E_INVALID_ARG, "Invalid argument is used. Language code is invalid. Given locale is not supported");
160 SysTryReturnResult(NID_LCL, locale.GetCountryCode() != COUNTRY_INVALID,
161 E_INVALID_ARG, "Invalid argument is used. Country code is invalid. Given locale is not supported");
163 std::unique_ptr< _IcuCalendarImpl > pCalendar(new (std::nothrow) _IcuCalendarImpl);
164 SysTryReturnResult(NID_LCL, pCalendar != null, E_OUT_OF_MEMORY, "Memory allocation failed");
166 result r = pCalendar->Construct(timeZone, locale, calendarType);
169 __pCalendar = pCalendar.release();
170 __type = calendarType;
172 __timezone = timeZone;
174 _pCalendarImpl = this;
182 _CalendarImpl::Construct(const Calendar& otherCalendar)
184 // Object is not allowed to construct twice
185 SysAssertf(__pCalendar == null,
186 "Already constructed! Calling Construct() twice or more on a same instance is not allowed for this class");
189 const _CalendarImpl* pOtherCalendar = dynamic_cast< const _CalendarImpl* >(&otherCalendar);
190 if ((pOtherCalendar != null) && (pOtherCalendar->__pCalendar != null))
194 __pCalendar = pOtherCalendar->__pCalendar->CloneN();
195 if (__pCalendar != null)
197 __type = pOtherCalendar->__type;
198 __locale = pOtherCalendar->__locale;
199 __timezone = pOtherCalendar->__timezone;
201 _pCalendarImpl = pOtherCalendar->_pCalendarImpl;
210 _CalendarImpl::SetTimeFieldImpl(TimeField field, int value)
212 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
213 SysTryReturnResult(NID_LCL, ValidateTimeField(field),
214 E_INVALID_ARG, "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
215 SysTryReturnResult(NID_LCL, ValidateTimeFieldValue(field, value), E_OUT_OF_RANGE, "value(%d) is out of range.", value);
217 return __pCalendar->SetTimeField(field, value);
221 _CalendarImpl::SetTimeInMillisecImpl(long long millisec)
223 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
224 return __pCalendar->SetTimeInMillisec(millisec - __timezone.GetRawOffset() * ONE_MINUTE_IN_MILLISEC);
228 _CalendarImpl::SetTimeImpl(const DateTime& dateTime)
230 return SetTimeImpl(dateTime.GetYear(), dateTime.GetMonth(), dateTime.GetDay(), dateTime.GetHour(), dateTime.GetMinute(), dateTime.GetSecond());
234 _CalendarImpl::SetTimeImpl(int year, int month, int day, int hour, int minute, int second)
236 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
237 SysTryReturnResult(NID_LCL, ValidateTimeFieldValue(TIME_FIELD_YEAR, year), E_OUT_OF_RANGE, "year(%d) is out of range.", year);
238 SysTryReturnResult(NID_LCL, ValidateTimeFieldValue(TIME_FIELD_MONTH, month), E_OUT_OF_RANGE, "month(%d) is out of range.", month);
239 SysTryReturnResult(NID_LCL, ValidateTimeFieldValue(TIME_FIELD_DAY_OF_MONTH, day), E_OUT_OF_RANGE, "day(%d) is out of range.", day);
240 SysTryReturnResult(NID_LCL, ValidateTimeFieldValue(TIME_FIELD_HOUR_OF_DAY, hour),E_OUT_OF_RANGE, "hour(%d) is out of range.", hour);
241 SysTryReturnResult(NID_LCL, ValidateTimeFieldValue(TIME_FIELD_MINUTE, minute), E_OUT_OF_RANGE, "minute(%d) is out of range.", minute);
242 SysTryReturnResult(NID_LCL, ValidateTimeFieldValue(TIME_FIELD_SECOND, second), E_OUT_OF_RANGE, "second(%d) is out of range.", second);
244 return __pCalendar->SetTime(year, month, day, hour, minute, second);
248 _CalendarImpl::SetFirstDayOfWeekImpl(DayOfWeek dayOfWeek)
250 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
251 SysTryReturnResult(NID_LCL, ValidateDaysOfWeek(dayOfWeek), E_INVALID_ARG, "Invalid argument is used. Unknown day of week");
253 return __pCalendar->SetFirstDayOfWeek(dayOfWeek);
257 _CalendarImpl::SetLenientImpl(bool lenient)
259 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
260 return __pCalendar->SetLenient(lenient);
264 _CalendarImpl::SetMinDaysInFirstWeekImpl(short value)
266 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
267 return __pCalendar->SetMinDaysInFirstWeek(value);
271 _CalendarImpl::SetTimeZoneImpl(const TimeZone& timeZone)
273 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
275 _timeZone = timeZone;
276 __timezone = timeZone;
277 return __pCalendar->SetTimeZone(__timezone);
281 _CalendarImpl::ClearImpl(void)
283 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
284 return __pCalendar->Clear();
288 _CalendarImpl::ClearImpl(TimeField field)
290 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
291 SysTryReturnResult(NID_LCL, ValidateTimeField(field), E_INVALID_ARG,
292 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
294 return __pCalendar->Clear(field);
298 _CalendarImpl::AddTimeField(TimeField field, int amount)
300 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
302 result r = E_INVALID_ARG;
304 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
309 SysTryReturnResult(NID_LCL, ValidateTimeField(field), r,
310 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
312 return __pCalendar->AddTimeField(field, amount);
316 _CalendarImpl::Roll(TimeField field, int amount)
318 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
320 result r = E_INVALID_ARG;
321 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
326 SysTryReturnResult(NID_LCL, ValidateTimeField(field), r,
327 "Invalid argument is used. Timefield is less than 0 or grater than time field count.");
329 return __pCalendar->Roll(field, amount);
333 _CalendarImpl::After(const _CalendarImpl& otherInstance, bool& after)
335 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
337 result r = E_INVALID_ARG;
338 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
343 SysTryReturnResult(NID_LCL, otherInstance.__pCalendar, r, "Invalid argument is used. otherCalendar instance is invalid");
345 return __pCalendar->After(*(otherInstance.__pCalendar), after);
349 _CalendarImpl::Before(const _CalendarImpl& otherInstance, bool& before)
351 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
353 result r = E_INVALID_ARG;
354 if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
359 SysTryReturnResult(NID_LCL, otherInstance.__pCalendar, r, "Invalid argument is used. otherCalendar instance is invalid");
361 return __pCalendar->Before(*(otherInstance.__pCalendar), before);
365 _CalendarImpl::Equals(const _CalendarImpl& otherInstance) const
367 if ((__pCalendar != null) && (otherInstance.__pCalendar != null))
369 return __pCalendar->Equals(*(otherInstance.__pCalendar));
371 return (__pCalendar == otherInstance.__pCalendar);
375 _CalendarImpl::GetHashCode(void) const
377 Integer intValues = IsLenient() + GetFirstDayOfWeek() + GetMinDaysInFirstWeek();
378 int hashCode = intValues.GetHashCode();
380 long long myTicks = 0;
381 GetTimeInMillisec(myTicks);
382 hashCode = (hashCode << 5) - hashCode + LongLong(myTicks).GetHashCode()+__timezone.GetHashCode();
388 _CalendarImpl::GetType(void) const
394 _CalendarImpl::GetTimeFieldImpl(TimeField field) const
396 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
397 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
398 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
400 return __pCalendar->GetTimeField(field);
404 _CalendarImpl::GetTimeInMillisecImpl(long long& millisec) const
406 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
408 long long tempMillisec;
410 r = __pCalendar->GetTimeInMillisec(tempMillisec);
411 SysTryReturnResult(NID_LCL, r == E_SUCCESS, r, "Unable to get time in milli sec");
412 millisec = tempMillisec + __timezone.GetRawOffset() * ONE_MINUTE_IN_MILLISEC;
417 _CalendarImpl::GetTimeImpl(void) const
419 int year = __pCalendar->GetTimeField(TIME_FIELD_YEAR);
420 int month = __pCalendar->GetTimeField(TIME_FIELD_MONTH);
421 int date = __pCalendar->GetTimeField(TIME_FIELD_DAY_OF_MONTH);
423 int hour = __pCalendar->GetTimeField(TIME_FIELD_HOUR_OF_DAY);
424 int minute = __pCalendar->GetTimeField(TIME_FIELD_MINUTE);
425 int second = __pCalendar->GetTimeField(TIME_FIELD_SECOND);
428 result r = dateTime.SetValue(year, month, date, hour, minute, second);
429 SysTryReturn(NID_LCL, r == E_SUCCESS, DateTime(), r, "[%s] Unable to set time in DateTime object", GetErrorMessage(r));
435 _CalendarImpl::GetMinTimeField(TimeField field) const
437 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
438 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
439 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
441 return __pCalendar->GetMinTimeField(field);
445 _CalendarImpl::GetActualMinTimeField(TimeField field) const
447 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
448 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
449 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
451 return __pCalendar->GetActualMinTimeField(field);
455 _CalendarImpl::GetGreatestMinTimeField(TimeField field) const
457 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
458 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
459 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
461 return __pCalendar->GetGreatestMinTimeField(field);
465 _CalendarImpl::GetLeastMaxTimeField(TimeField field) const
467 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
468 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
469 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
471 return __pCalendar->GetLeastMaxTimeField(field);
475 _CalendarImpl::GetActualMaxTimeField(TimeField field) const
477 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
478 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
479 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
481 return __pCalendar->GetActualMaxTimeField(field);
485 _CalendarImpl::GetMaxTimeField(TimeField field) const
487 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
488 SysTryReturn(NID_LCL, ValidateTimeField(field), -1, E_INVALID_ARG,
489 "[%s] Invalid argument is used. Timefield is less than 0 or grater than time field count.", GetErrorMessage(E_INVALID_ARG));
491 return __pCalendar->GetMaxTimeField(field);
495 _CalendarImpl::GetFirstDayOfWeekImpl(void) const
497 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
498 return __pCalendar->GetFirstDayOfWeek();
502 _CalendarImpl::GetMinDaysInFirstWeekImpl(void) const
504 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
505 return __pCalendar->GetMinDaysInFirstWeek();
509 _CalendarImpl::IsInDst(bool& isInDst) const
511 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
512 return __pCalendar->IsInDst(isInDst);
516 _CalendarImpl::IsLenientImpl(void) const
518 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
519 return __pCalendar->IsLenient();
523 _CalendarImpl::IsSetImpl(TimeField field) const
525 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
526 return __pCalendar->IsSet(field);
530 _CalendarImpl::GetTimeZoneImpl(void) const
536 _CalendarImpl::IsLeapYear(int year) const
538 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
539 return __pCalendar->IsLeapYear(year);
543 _CalendarImpl::SetGregorianChange(long long change)
545 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
546 return __pCalendar->SetGregorianChange(change);
550 _CalendarImpl::GetGregorianChange(void) const
552 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
553 return __pCalendar->GetGregorianChange();
557 _CalendarImpl::SetJulianDay(int julianDay)
559 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
560 return __pCalendar->SetJulianDay(julianDay);
564 _CalendarImpl::GetJulianDay(void) const
566 SysAssertf(__pCalendar != null, "Not yet constructed! Construct() should be called before use.");
567 return __pCalendar->GetJulianDay();
571 _CalendarImpl::ValidateTimeField(TimeField field) const
573 if (field < 0 || field >= TIME_FIELD_FIELD_COUNT)
581 _CalendarImpl::ValidateTimeFieldValue(TimeField field, int value) const
583 if (IsLenientImpl() == false)
585 if ((value < GetMinTimeField(field)) || (value > GetMaxTimeField(field)))
595 _CalendarImpl::ValidateDaysOfWeek(DayOfWeek dayOfWeek) const
597 if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY)
604 // added for backward compatibility
606 _CalendarImpl::RollWithSingleUnit(TimeField field, bool up)
608 return E_UNSUPPORTED_OPERATION;
611 // added for backward compatibility
613 _CalendarImpl::ComputeTimeFields(void)
615 return E_UNSUPPORTED_OPERATION;
618 // added for backward compatibility
620 _CalendarImpl::ComputeTime(void)
622 return E_UNSUPPORTED_OPERATION;
625 // added for backward compatibility
627 _CalendarImpl::GetMonthLength(int extendedYear, int month) const
629 SetLastResult(E_UNSUPPORTED_OPERATION);
633 // added for backward compatibility
635 _CalendarImpl::HandleGetLimit(TimeField field, CalendarLimitType limitType) const
637 SetLastResult(E_UNSUPPORTED_OPERATION);
641 const _IcuCalendarImpl*
642 _CalendarImpl::GetImpl(const Calendar& calendar)
644 if (calendar._pCalendarImpl)
646 return calendar._pCalendarImpl->__pCalendar;