Merge "Refactoy Locales for DateTimeFormatter." into devel_3.0_main
[platform/framework/native/appfw.git] / src / locales / FLcl_DateTimeFormatterImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 //
16
17 /**
18  * @file        FLclDateTimeFormatter.cpp
19  * @brief       This is the implementation file for DateTimeFormatter class.
20  */
21
22 // Includes
23 #include <unique_ptr.h>
24 #include <unicode/dtfmtsym.h>
25 #include <unicode/smpdtfmt.h>
26 #include <unicode/calendar.h>
27
28 #include <FBaseSysLog.h>
29 #include <FApp_AppInfo.h>
30 #include <FLclDateTimeFormatter.h>
31 #include "FLcl_DateTimeFormatterImpl.h"
32 #include "FLcl_LocaleData.h"
33 #include "FLcl_LocaleManagerImpl.h"
34 #include "FLcl_CalendarImpl.h"
35 #include "FLcl_IcuCalendarImpl.h"
36 #include "FLcl_DateTimeSymbolsImpl.h"
37
38 using namespace Tizen::Base;
39 using namespace Tizen::Base::Collection;
40 using namespace Tizen::Base::Utility;
41
42 namespace Tizen { namespace Locales
43 {
44
45 _DateTimeFormatterImpl::_DateTimeFormatterImpl(void)
46         : __pSymbols(null)
47         , __pIcuDateFormatter(null)
48         , __pLocale(null)
49 {
50 }
51
52 _DateTimeFormatterImpl::~_DateTimeFormatterImpl(void)
53 {
54         delete __pSymbols;
55         delete __pIcuDateFormatter;
56         delete __pLocale;
57 }
58
59 // The DateTimeFormatter always use System Locale if not provided by the user.
60 // System locale may be different for default ICU locale.
61 DateTimeFormatter*
62 _DateTimeFormatterImpl::CreateInstanceN(DateTimeStyle dateStyle, DateTimeStyle timeStyle)
63 {
64         result r = E_INVALID_ARG;
65
66         if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
67         {
68                 r = E_UNSUPPORTED_OPERATION;
69         }
70
71         SysTryReturn(NID_LCL, ValidateDateTimeStyle(dateStyle), null, r, "[%s] Invalid argument is used. dateStyle is invalid", GetErrorMessage(r));
72         SysTryReturn(NID_LCL, ValidateDateTimeStyle(timeStyle), null, r, "[%s] Invalid argument is used. timeStyle is invalid", GetErrorMessage(r));
73
74         // using system locale, may be different from ICU default locale
75         DateTimeFormatter* pDateTimeFormatter = CreateInstanceN(_LocaleManagerImpl::GetSystemLocale(), dateStyle, timeStyle);
76
77         if (GetLastResult() == E_INVALID_ARG)
78         {
79                 SetLastResult(E_UNSUPPORTED_OPERATION);
80         }
81         return pDateTimeFormatter;
82 }
83
84 DateTimeFormatter*
85 _DateTimeFormatterImpl::CreateInstanceN(const Locale& locale, DateTimeStyle dateStyle, DateTimeStyle timeStyle)
86 {
87         result r = (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat()) ? E_UNSUPPORTED_OPERATION : E_INVALID_ARG;
88
89         SysTryReturn(NID_LCL, locale.GetLanguageCode() != LANGUAGE_INVALID && locale.GetCountryCode() != COUNTRY_INVALID, null, r, "It is the invalid locale.");
90         SysTryReturn(NID_LCL, ValidateDateTimeStyle(dateStyle), null, r, "[%s] Invalid argument is used. dateStyle is invalid", GetErrorMessage(r));
91         SysTryReturn(NID_LCL, ValidateDateTimeStyle(timeStyle), null, r, "[%s] Invalid argument is used. timeStyle is invalid", GetErrorMessage(r));
92
93         ClearLastResult();
94
95         std::unique_ptr<DateTimeFormatter> pDateTimeFormatter(new (std::nothrow) DateTimeFormatter());
96         SysTryReturn(NID_LCL, pDateTimeFormatter, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
97
98         std::unique_ptr<_DateTimeFormatterImpl> pDateTimeFormatterImpl(new (std::nothrow) _DateTimeFormatterImpl);
99         SysTryReturn(NID_LCL,pDateTimeFormatterImpl, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
100
101         std::unique_ptr< U_ICU_NAMESPACE::SimpleDateFormat> pIcuDateFormatter(pDateTimeFormatterImpl->GetIcuDateFormatterN(locale, dateStyle, timeStyle));
102         SysTryReturn(NID_LCL, pIcuDateFormatter, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
103
104         pDateTimeFormatterImpl->__pLocale = new (std::nothrow) Locale(locale);
105         SysTryReturn(NID_LCL, pDateTimeFormatterImpl->__pLocale, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
106         pDateTimeFormatterImpl->__pIcuDateFormatter = pIcuDateFormatter.release();
107         pDateTimeFormatter->__pDateTimeFormatterImpl = pDateTimeFormatterImpl.release();
108         return pDateTimeFormatter.release();      // Here as LastResult is already cleared, no need to set it to E_SUCCESS
109 }
110
111 U_ICU_NAMESPACE::SimpleDateFormat*
112 _DateTimeFormatterImpl::GetIcuDateFormatterN(const Locale& locale, DateTimeStyle dateStyle, DateTimeStyle timeStyle)
113 {
114         SysTryReturn(NID_LCL, dateStyle != DATE_TIME_STYLE_NONE || timeStyle != DATE_TIME_STYLE_NONE, null, E_INVALID_ARG, "It is an invalid argument.");
115
116         U_ICU_NAMESPACE::DateFormat* pIcuDateFormat = null;
117         U_ICU_NAMESPACE::DateFormat::EStyle icuDateStyle = (U_ICU_NAMESPACE::DateFormat::EStyle) dateStyle;
118         U_ICU_NAMESPACE::DateFormat::EStyle icuTimeStyle = (U_ICU_NAMESPACE::DateFormat::EStyle) timeStyle;
119         U_ICU_NAMESPACE::Locale icuLocale = _LocaleData::GetIcuLocale(locale);
120
121         if (dateStyle != DATE_TIME_STYLE_NONE && timeStyle != DATE_TIME_STYLE_NONE)
122         {
123                 pIcuDateFormat = U_ICU_NAMESPACE::DateFormat::createDateTimeInstance(icuDateStyle, icuTimeStyle, icuLocale);
124         }
125         else if (dateStyle != DATE_TIME_STYLE_NONE && timeStyle == DATE_TIME_STYLE_NONE)
126         {
127                 pIcuDateFormat = U_ICU_NAMESPACE::DateFormat::createDateInstance(icuDateStyle, icuLocale);
128         }
129         else if (dateStyle == DATE_TIME_STYLE_NONE && timeStyle != DATE_TIME_STYLE_NONE)
130         {
131                 pIcuDateFormat = U_ICU_NAMESPACE::DateFormat::createTimeInstance(icuTimeStyle, icuLocale);
132         }
133
134         return dynamic_cast< U_ICU_NAMESPACE::SimpleDateFormat* >(pIcuDateFormat);
135 }
136
137
138 // This function will not have TimeZone informations and always print time zone as GMT+00:00
139 result
140 _DateTimeFormatterImpl::Format(const DateTime& date, String& strBuf) const
141 {
142         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
143
144         std::unique_ptr< Calendar > pCal(Calendar::CreateInstanceN());
145         SysTryReturnResult(NID_LCL, pCal, E_OUT_OF_MEMORY, "Memory allocation failed");
146
147         result r = pCal->SetTime(date);
148         SysTryReturn(NID_LCL, r == E_SUCCESS, r, r, "[%s] Unable to set date time in default calendar", GetErrorMessage(r));
149
150         r = pCal->Clear(TIME_FIELD_MILLISECOND);
151         SysTryReturn(NID_LCL, r == E_SUCCESS, r, r, "[%s] Unable to set date time in default calendar", GetErrorMessage(r));
152
153         return Format(*(pCal.get()), strBuf);
154 }
155
156 result
157 _DateTimeFormatterImpl::Format(const Calendar& calendar, String& strBuf) const
158 {
159         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
160
161         const _IcuCalendarImpl* pIcuCalendarImpl = _CalendarImpl::GetImpl(calendar);
162         SysTryReturnResult(NID_LCL, pIcuCalendarImpl, E_SYSTEM, "It is failed to get icu calendar.");
163
164         IcuCalendar* pIcuCal = pIcuCalendarImpl->GetIcuCalendarCloneN();
165         SysTryReturnResult(NID_LCL, pIcuCal, E_SYSTEM, "It is failed to get icu calendar.");
166
167         IcuFieldPosition icuFp;
168         IcuUnicodeString icuStr;
169
170         _LocaleData::GetIcuString(strBuf,icuStr);
171         icuStr = __pIcuDateFormatter->format(*pIcuCal, icuStr, icuFp);
172         strBuf = _LocaleData::GetOspString(icuStr);
173         delete pIcuCal;
174
175         return E_SUCCESS;
176 }
177
178 result
179 _DateTimeFormatterImpl::ApplyPattern(const String& pattern)
180 {
181         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
182         U_ICU_NAMESPACE::UnicodeString icuStr;
183         _LocaleData::GetIcuString(pattern, icuStr);
184         __pIcuDateFormatter->applyPattern(icuStr);
185         return E_SUCCESS;
186 }
187
188 String
189 _DateTimeFormatterImpl::GetPattern(void) const
190 {
191         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
192         IcuUnicodeString icuPattern;
193         icuPattern = __pIcuDateFormatter->toPattern(icuPattern);
194         return _LocaleData::GetOspString(icuPattern);
195 }
196
197 const DateTimeSymbols*
198 _DateTimeFormatterImpl::GetDateTimeSymbols(void)
199 {
200         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
201         if (__pSymbols == null)
202         {
203                 std::unique_ptr< DateTimeSymbols > pSymbols(new (std::nothrow) DateTimeSymbols);
204                 SysTryReturn(NID_LCL, pSymbols, null, E_OUT_OF_MEMORY, "It is not enough memory.");
205                 pSymbols->Construct(*__pLocale);
206                 __pSymbols = pSymbols.release();
207         }
208         return __pSymbols;
209 }
210
211 void
212 _DateTimeFormatterImpl::SetDateTimeSymbols(const DateTimeSymbols& newSymbols)
213 {
214         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
215
216         std::unique_ptr< DateTimeSymbols > pSymbols(new (std::nothrow) DateTimeSymbols);
217         SysTryReturn(NID_LCL, pSymbols, , E_OUT_OF_MEMORY, "It is not enough memory.");
218         result r = pSymbols->Construct(newSymbols);
219         SysTryReturn(NID_LCL, r == E_SUCCESS, , r, "[%s] occured.", GetErrorMessage(r));
220
221         _DateTimeSymbolsImpl* pDateTimeSymbolsImpl = _DateTimeSymbolsImpl::GetDateTimeSymbolsImpl(pSymbols.get());
222         const U_ICU_NAMESPACE::DateFormatSymbols* pIcuSymbols = pDateTimeSymbolsImpl->GetIcuSymbols();
223
224         __pIcuDateFormatter->setDateFormatSymbols(*pIcuSymbols);
225
226         if (__pSymbols)
227         {
228                 delete __pSymbols;
229         }
230         __pSymbols = pSymbols.release();
231 }
232
233 bool
234 _DateTimeFormatterImpl::ValidateDateTimeStyle(DateTimeStyle dateTimeStyle)
235 {
236         return (dateTimeStyle < DATE_TIME_STYLE_NONE || dateTimeStyle > DATE_TIME_STYLE_SHORT) ? false : true;
237 }
238
239 };
240 };      // Tizen::Locales