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 FLclGregorianCalendar.cpp
20 * @brief This is the implementation file for GregorianCalendar class.
23 #include <unique_ptr.h>
25 #include <FBaseDateTime.h>
26 #include <FBaseSysLog.h>
27 #include <FLclGregorianCalendar.h>
28 #include "FLcl_CalendarImpl.h"
29 #include "FLcl_LocaleManagerImpl.h"
31 using namespace Tizen::Base;
33 namespace Tizen { namespace Locales
36 //////////////////////////////////////////////////////////////////////////////////
38 const int GregorianCalendar::MONTH_LENGTH[24] =
40 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, // Days in month in normal year
41 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 // Days in month in leap year
44 // Set cumulative number of days at first day of month
45 const int GregorianCalendar::NUM_DAYS[24] =
47 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, // Cumulative number of days at first day of month in normal year
48 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 // Cumulative number of days at first day of month in leap year
51 GregorianCalendar::GregorianCalendar(void)
52 : __normalizedGregorianCutover(DEFAULT_GREGORIAN_CUTOVER)
53 , __gregorianCutoverYear(1582)
54 , __cutoverJulianDay(GregorianCalendar::CUTOVER_JULIAN_DAY)
55 , __pGregorianCalendarImpl(null)
59 GregorianCalendar::~GregorianCalendar(void)
61 delete _pCalendarImpl;
62 _pCalendarImpl = null;
65 // This method is copy constructor
67 GregorianCalendar::Construct(const GregorianCalendar& gc)
69 // Object is not allowed to construct twice
70 SysAssertf(_pCalendarImpl == null,
71 "Already constructed! Calling Construct() twice or more on a same instance is not allowed for this class");
73 if (gc._pCalendarImpl != null)
75 std::unique_ptr< Calendar > pCalendar(gc._pCalendarImpl->CloneN());
76 SysTryReturnResult(NID_LCL, pCalendar != null, E_OUT_OF_MEMORY, "Memory allocation failed");
78 _pCalendarImpl = dynamic_cast< _CalendarImpl* >(pCalendar.get());
79 if (_pCalendarImpl != null)
83 __cutoverJulianDay = gc.__cutoverJulianDay;
84 __normalizedGregorianCutover = gc.__normalizedGregorianCutover;
85 __gregorianCutoverYear = gc.__gregorianCutoverYear;
93 GregorianCalendar::Construct(void)
95 return Construct(TimeZone::GetGmtTimeZone(), _LocaleManagerImpl::GetSystemLocale());
99 GregorianCalendar::Construct(const TimeZone& timezone)
101 return Construct(timezone, _LocaleManagerImpl::GetSystemLocale());
105 GregorianCalendar::Construct(const Locale& locale)
107 return Construct(TimeZone::GetGmtTimeZone(), locale);
111 GregorianCalendar::Construct(const TimeZone& timezone, const Locale& locale)
113 // Object is not allowed to construct twice
114 SysAssertf(_pCalendarImpl == null,
115 "Already constructed! Calling Construct() twice or more on a same instance is not allowed for this class");
117 std::unique_ptr< _CalendarImpl > pCalendarImpl(new (std::nothrow) _CalendarImpl);
118 SysTryReturnResult(NID_LCL, pCalendarImpl != null, E_OUT_OF_MEMORY, "Memory allocation failed");
120 result r = pCalendarImpl->Construct(timezone, locale);
123 _pCalendarImpl = pCalendarImpl.release();
125 SetGregorianChange(GetGregorianChange());
133 GregorianCalendar::Construct(int year, int month, int day, int hourOfDay, int minute, int second)
135 result r = Construct(TimeZone::GetGmtTimeZone(), _LocaleManagerImpl::GetSystemLocale());
138 r = SetTime(year, month, day, hourOfDay, minute, second);
144 GregorianCalendar::Construct(const DateTime& dateTime)
146 return Construct(dateTime.GetYear(),
150 dateTime.GetMinute(),
151 dateTime.GetSecond());
155 GregorianCalendar::AddTimeField(TimeField field, int amount)
157 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
158 return _pCalendarImpl->AddTimeField(field, amount);
162 GregorianCalendar::DayToFields(int day, int& year, int& month, int& dayOfMonth, int& dayOfWeek, int& dayOfYear)
164 _CalendarImpl calImpl;
165 result r = calImpl.Construct();
168 r = calImpl.SetJulianDay(day + GregorianCalendar::EPOCH_START_AS_JULIAN_DAY);
171 year = calImpl.GetTimeField(TIME_FIELD_YEAR);
172 month = calImpl.GetTimeField(TIME_FIELD_MONTH);
173 dayOfMonth = calImpl.GetTimeField(TIME_FIELD_DAY_OF_MONTH);
174 dayOfWeek = calImpl.GetTimeField(TIME_FIELD_DAY_OF_WEEK);
175 dayOfYear = calImpl.GetTimeField(TIME_FIELD_DAY_OF_YEAR);
180 // This method gets the actual minimum value that a given field could have.
181 // For Gregorian calendar, it is the same as GetMinTimeField() and GetGreatestMinimum()
183 GregorianCalendar::GetActualMinTimeField(TimeField field) const
185 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
186 return _pCalendarImpl->GetActualMinTimeField(field);
190 // This method gets the actual maximum value that this field could have, given the current date.
191 // This method has a limitation (also GetActualMinimum). It will not behave properly at the extreme limits of Gregorian calendar's
192 // representable range.
193 // For calendars with the default Gregorian cutover, these limits are Sun Dec 02 16:47:04 GMT 292269055 BC to Sun
194 // Aug 17 07:12:55 GMT 292278994 AD, somewhat different for non-GMT zones.
195 // As a result, if the calendar is set to Aug 1 292278994 AD, the actual maximum of DAY_OF_MONTH is 17, not 30.
198 GregorianCalendar::GetActualMaxTimeField(TimeField field) const
200 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
201 return _pCalendarImpl->GetActualMaxTimeField(field);
204 //This method returns the Gregorian cutover.
206 GregorianCalendar::GetGregorianChange(void) const
208 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
209 return _pCalendarImpl->GetGregorianChange();
213 GregorianCalendar::GetType(void) const
215 return CALENDAR_GREGORIAN;
219 GregorianCalendar::IsInDst(bool& isInDst) const
221 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
222 return _pCalendarImpl->IsInDst(isInDst);
226 GregorianCalendar::IsLeapYear(int year) const
228 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
229 return _pCalendarImpl->IsLeapYear(year);
233 GregorianCalendar::Roll(TimeField field, int amount)
235 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
236 return _pCalendarImpl->Roll(field, amount);
240 GregorianCalendar::SetGregorianChange(long long change)
242 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
244 result r = E_SUCCESS;
245 if (_pCalendarImpl->GetGregorianChange() != change)
247 r = _pCalendarImpl->SetGregorianChange(change);
250 std::unique_ptr< Calendar > pCalendar(_pCalendarImpl->CloneN());
251 SysTryReturnResult(NID_LCL, pCalendar != null, E_OUT_OF_MEMORY, "Memory allocation failed");
253 _CalendarImpl* pCalImpl = dynamic_cast< _CalendarImpl* >(pCalendar.get());
254 if (pCalImpl != null)
256 pCalImpl->SetTimeInMillisec(change);
258 __cutoverJulianDay = pCalImpl->GetJulianDay();
259 // __normalizedGregorianCutover = change * Calendar::ONE_DAY_IN_MILLISEC;
261 __gregorianCutoverYear = pCalImpl->GetTimeField(TIME_FIELD_YEAR);
262 if (pCalImpl->GetTimeField(TIME_FIELD_ERA) == GREGORIAN_CALENDAR_BC)
264 __gregorianCutoverYear = 1 - __gregorianCutoverYear; // update __gregorianCutoverYear for BC, 0 based
267 long long julianDayFromEpoch = __cutoverJulianDay - GregorianCalendar::EPOCH_START_AS_JULIAN_DAY;
268 __normalizedGregorianCutover = julianDayFromEpoch * Calendar::ONE_DAY_IN_MILLISEC;
270 // Handle the rare case of numeric overflow
271 if (julianDayFromEpoch < 0 && __normalizedGregorianCutover > 0)
273 __normalizedGregorianCutover = (julianDayFromEpoch + 1) * Calendar::ONE_DAY_IN_MILLISEC;
281 GregorianCalendar::IsGregorian(void) const
287 GregorianCalendar::GetNormalizedGregorianCutover(void) const
289 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
290 return __normalizedGregorianCutover;
294 GregorianCalendar::GetGregorianCutoverYear(void) const
296 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
297 return __gregorianCutoverYear;
301 GregorianCalendar::GetCutoverJulianDay(void) const
303 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
304 return __cutoverJulianDay;
308 GregorianCalendar::GetTimeInMillisecFromEpoch(long long& millisec) const
310 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
311 result r = _pCalendarImpl->GetTimeInMillisec(millisec);
314 millisec -= GregorianCalendar::EPOCH_OFFSET_IN_MILLISEC;
320 GregorianCalendar::SetTimeInMillisecFromEpoch(long long millisec)
322 SysAssertf(_pCalendarImpl != null, "Not yet constructed! Construct() should be called before use.");
324 millisec += GregorianCalendar::EPOCH_OFFSET_IN_MILLISEC;
325 return _pCalendarImpl->SetTimeInMillisec(millisec);
328 // added for backward compatibility
330 GregorianCalendar::RollWithSingleUnit(TimeField field, bool up)
332 return E_UNSUPPORTED_OPERATION;
335 // added for backward compatibility
337 GregorianCalendar::ComputeTimeFields(void)
339 return E_UNSUPPORTED_OPERATION;
342 // added for backward compatibility
344 GregorianCalendar::ComputeTime(void)
346 return E_UNSUPPORTED_OPERATION;
349 // added for backward compatibility
351 GregorianCalendar::GetMonthLength(int extendedYear, int month) const
353 SetLastResult(E_UNSUPPORTED_OPERATION);
357 // added for backward compatibility
359 GregorianCalendar::HandleGetLimit(TimeField field, CalendarLimitType limitType) const
361 SetLastResult(E_UNSUPPORTED_OPERATION);
365 // added for backward compatibility
367 GregorianCalendar::CloneN(void) const
369 SetLastResult(E_UNSUPPORTED_OPERATION);