Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <rtl/strbuf.hxx>
21 : #include <unotools/calendarwrapper.hxx>
22 : #include <com/sun/star/i18n/CalendarFieldIndex.hpp>
23 : #include <com/sun/star/i18n/LocaleCalendar.hpp>
24 :
25 : using namespace ::com::sun::star;
26 : using namespace ::com::sun::star::i18n;
27 : using namespace ::com::sun::star::uno;
28 :
29 : const double MILLISECONDS_PER_DAY = 1000.0 * 60.0 * 60.0 * 24.0;
30 :
31 400 : CalendarWrapper::CalendarWrapper(
32 : const Reference< uno::XComponentContext > & rxContext
33 : )
34 : :
35 400 : aEpochStart( Date( 1, 1, 1970 ) )
36 : {
37 400 : xC = LocaleCalendar::create(rxContext);
38 400 : }
39 :
40 390 : CalendarWrapper::~CalendarWrapper()
41 : {
42 390 : }
43 :
44 1358 : void CalendarWrapper::loadDefaultCalendar( const ::com::sun::star::lang::Locale& rLocale )
45 : {
46 : try
47 : {
48 1358 : if ( xC.is() )
49 1358 : xC->loadDefaultCalendar( rLocale );
50 : }
51 0 : catch (const Exception& e)
52 : {
53 : SAL_WARN( "unotools.i18n", "loadDefaultCalendar: Exception caught " << e.Message );
54 : }
55 1358 : }
56 :
57 24 : void CalendarWrapper::loadCalendar( const OUString& rUniqueID, const ::com::sun::star::lang::Locale& rLocale )
58 : {
59 : try
60 : {
61 24 : if ( xC.is() )
62 24 : xC->loadCalendar( rUniqueID, rLocale );
63 : }
64 0 : catch (const Exception& e)
65 : {
66 : SAL_WARN( "unotools.i18n", "loadCalendar: Exception caught requested: "
67 : << rUniqueID << " Locale: " << rLocale.Language << "_" << rLocale.Country << " " << e.Message );
68 : }
69 24 : }
70 :
71 4 : ::com::sun::star::uno::Sequence< OUString > CalendarWrapper::getAllCalendars( const ::com::sun::star::lang::Locale& rLocale ) const
72 : {
73 : try
74 : {
75 4 : if ( xC.is() )
76 4 : return xC->getAllCalendars( rLocale );
77 : }
78 0 : catch (const Exception& e)
79 : {
80 : SAL_WARN( "unotools.i18n", "getAllCalendars: Exception caught " << e.Message );
81 : }
82 :
83 0 : return ::com::sun::star::uno::Sequence< OUString > (0);
84 : }
85 :
86 4508 : OUString CalendarWrapper::getUniqueID() const
87 : {
88 : try
89 : {
90 4508 : if ( xC.is() )
91 4508 : return xC->getUniqueID();
92 : }
93 0 : catch (const Exception& e)
94 : {
95 : SAL_WARN( "unotools.i18n", "getUniqueID: Exception caught " << e.Message );
96 : }
97 0 : return OUString();
98 : }
99 :
100 12 : void CalendarWrapper::setDateTime( double fTimeInDays )
101 : {
102 : try
103 : {
104 12 : if ( xC.is() )
105 12 : xC->setDateTime( fTimeInDays );
106 : }
107 0 : catch (const Exception& e)
108 : {
109 : SAL_WARN( "unotools.i18n", "setDateTime: Exception caught " << e.Message );
110 : }
111 12 : }
112 :
113 12 : double CalendarWrapper::getDateTime() const
114 : {
115 : try
116 : {
117 12 : if ( xC.is() )
118 12 : return xC->getDateTime();
119 : }
120 0 : catch (const Exception& e)
121 : {
122 : SAL_WARN( "unotools.i18n", "getDateTime: Exception caught " << e.Message );
123 : }
124 0 : return 0.0;
125 : }
126 :
127 11848 : sal_Int32 CalendarWrapper::getCombinedOffsetInMillis(
128 : sal_Int16 nParentFieldIndex, sal_Int16 nChildFieldIndex ) const
129 : {
130 11848 : sal_Int32 nOffset = 0;
131 : try
132 : {
133 11848 : if ( xC.is() )
134 : {
135 11848 : nOffset = static_cast<sal_Int32>( xC->getValue( nParentFieldIndex )) * 60000;
136 11848 : sal_Int16 nSecondMillis = xC->getValue( nChildFieldIndex );
137 11848 : if (nOffset < 0)
138 12 : nOffset -= static_cast<sal_uInt16>( nSecondMillis);
139 : else
140 11836 : nOffset += static_cast<sal_uInt16>( nSecondMillis);
141 : }
142 : }
143 0 : catch (const Exception& e)
144 : {
145 : SAL_WARN( "unotools.i18n", "getCombinedOffsetInMillis: Exception caught " << e.Message );
146 : }
147 11848 : return nOffset;
148 : }
149 :
150 5924 : sal_Int32 CalendarWrapper::getZoneOffsetInMillis() const
151 : {
152 : return getCombinedOffsetInMillis( CalendarFieldIndex::ZONE_OFFSET,
153 5924 : CalendarFieldIndex::ZONE_OFFSET_SECOND_MILLIS);
154 : }
155 :
156 5924 : sal_Int32 CalendarWrapper::getDSTOffsetInMillis() const
157 : {
158 : return getCombinedOffsetInMillis( CalendarFieldIndex::DST_OFFSET,
159 5924 : CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS);
160 : }
161 :
162 2838 : void CalendarWrapper::setLocalDateTime( double fTimeInDays )
163 : {
164 : try
165 : {
166 2838 : if ( xC.is() )
167 : {
168 : // First set a nearby value to obtain the timezone and DST offset.
169 : // This is necessary to let ICU choose the corresponding
170 : // OlsonTimeZone transitions. Since ICU incorporates also
171 : // historical data even the timezone may differ for different
172 : // dates! (Which was the cause for #i76623# when the timezone of a
173 : // previously set date was used.) Timezone may also include
174 : // seconds, so use milliseconds field as well.
175 2838 : xC->setDateTime( fTimeInDays );
176 2838 : sal_Int32 nZone1 = getZoneOffsetInMillis();
177 2838 : sal_Int32 nDST1 = getDSTOffsetInMillis();
178 2838 : double fLoc = fTimeInDays - (double)(nZone1 + nDST1) / MILLISECONDS_PER_DAY;
179 2838 : xC->setDateTime( fLoc );
180 2838 : sal_Int32 nZone2 = getZoneOffsetInMillis();
181 2838 : sal_Int32 nDST2 = getDSTOffsetInMillis();
182 : // If DSTs differ after calculation, we crossed boundaries. Do it
183 : // again, this time using the DST corrected initial value for the
184 : // real local time.
185 : // See also localtime/gmtime conversion pitfalls at
186 : // http://www.erack.de/download/timetest.c
187 2838 : if ( nDST1 != nDST2 )
188 : {
189 0 : fLoc = fTimeInDays - (double)(nZone2 + nDST2) / MILLISECONDS_PER_DAY;
190 0 : xC->setDateTime( fLoc );
191 : // #i17222# If the DST onset rule says to switch from 00:00 to
192 : // 01:00 and we tried to set onsetDay 00:00 with DST, the
193 : // result was onsetDay-1 23:00 and no DST, which is not what we
194 : // want. So once again without DST, resulting in onsetDay
195 : // 01:00 and DST. Yes, this seems to be weird, but logically
196 : // correct.
197 0 : sal_Int32 nDST3 = getDSTOffsetInMillis();
198 0 : if ( nDST2 != nDST3 && !nDST3 )
199 : {
200 0 : fLoc = fTimeInDays - (double)(nZone2 + nDST3) / MILLISECONDS_PER_DAY;
201 0 : xC->setDateTime( fLoc );
202 : }
203 : }
204 : }
205 : }
206 0 : catch (const Exception& e)
207 : {
208 : SAL_WARN( "unotools.i18n", "setLocalDateTime: Exception caught " << e.Message );
209 : }
210 2838 : }
211 :
212 248 : double CalendarWrapper::getLocalDateTime() const
213 : {
214 : try
215 : {
216 248 : if ( xC.is() )
217 : {
218 248 : double fTimeInDays = xC->getDateTime();
219 248 : sal_Int32 nZone = getZoneOffsetInMillis();
220 248 : sal_Int32 nDST = getDSTOffsetInMillis();
221 248 : fTimeInDays += (double)(nZone + nDST) / MILLISECONDS_PER_DAY;
222 248 : return fTimeInDays;
223 : }
224 : }
225 0 : catch (const Exception& e)
226 : {
227 : SAL_WARN( "unotools.i18n", "getLocalDateTime: Exception caught " << e.Message );
228 : }
229 0 : return 0.0;
230 : }
231 :
232 992 : void CalendarWrapper::setValue( sal_Int16 nFieldIndex, sal_Int16 nValue )
233 : {
234 : try
235 : {
236 992 : if ( xC.is() )
237 992 : xC->setValue( nFieldIndex, nValue );
238 : }
239 0 : catch (const Exception& e)
240 : {
241 : SAL_WARN( "unotools.i18n", "setValue: Exception caught " << e.Message );
242 : }
243 992 : }
244 :
245 248 : bool CalendarWrapper::isValid() const
246 : {
247 : try
248 : {
249 248 : if ( xC.is() )
250 248 : return xC->isValid();
251 : }
252 0 : catch (const Exception& e)
253 : {
254 : SAL_WARN( "unotools.i18n", "isValid: Exception caught " << e.Message );
255 : }
256 0 : return false;
257 : }
258 :
259 292 : sal_Int16 CalendarWrapper::getValue( sal_Int16 nFieldIndex ) const
260 : {
261 : try
262 : {
263 292 : if ( xC.is() )
264 292 : return xC->getValue( nFieldIndex );
265 : }
266 0 : catch (const Exception& e)
267 : {
268 : SAL_WARN( "unotools.i18n", "getValue: Exception caught " << e.Message );
269 : }
270 0 : return 0;
271 : }
272 :
273 0 : void CalendarWrapper::addValue( sal_Int16 nFieldIndex, sal_Int32 nAmount )
274 : {
275 : try
276 : {
277 0 : if ( xC.is() )
278 0 : xC->addValue( nFieldIndex, nAmount );
279 : }
280 0 : catch (const Exception& e)
281 : {
282 : SAL_WARN( "unotools.i18n", "addValue: Exception caught " << e.Message );
283 : }
284 0 : }
285 :
286 0 : sal_Int16 CalendarWrapper::getFirstDayOfWeek() const
287 : {
288 : try
289 : {
290 0 : if ( xC.is() )
291 0 : return xC->getFirstDayOfWeek();
292 : }
293 0 : catch (const Exception& e)
294 : {
295 : SAL_WARN( "unotools.i18n", "getFirstDayOfWeek: Exception caught " << e.Message );
296 : }
297 0 : return 0;
298 : }
299 :
300 7398 : sal_Int16 CalendarWrapper::getNumberOfMonthsInYear() const
301 : {
302 : try
303 : {
304 7398 : if ( xC.is() )
305 7398 : return xC->getNumberOfMonthsInYear();
306 : }
307 0 : catch (const Exception& e)
308 : {
309 : SAL_WARN( "unotools.i18n", "getNumberOfMonthsInYear: Exception caught " << e.Message );
310 : }
311 0 : return 0;
312 : }
313 :
314 3864 : sal_Int16 CalendarWrapper::getNumberOfDaysInWeek() const
315 : {
316 : try
317 : {
318 3864 : if ( xC.is() )
319 3864 : return xC->getNumberOfDaysInWeek();
320 : }
321 0 : catch (const Exception& e)
322 : {
323 : SAL_WARN( "unotools.i18n", "getNumberOfDaysInWeek: Exception caught " << e.Message );
324 : }
325 0 : return 0;
326 : }
327 :
328 2842 : ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getMonths() const
329 : {
330 : try
331 : {
332 2842 : if ( xC.is() )
333 2842 : return xC->getMonths2();
334 : }
335 0 : catch (const Exception& e)
336 : {
337 : SAL_WARN( "unotools.i18n", "getMonths: Exception caught " << e.Message );
338 : }
339 0 : return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
340 : }
341 :
342 1106 : ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getDays() const
343 : {
344 : try
345 : {
346 1106 : if ( xC.is() )
347 1106 : return xC->getDays2();
348 : }
349 0 : catch (const Exception& e)
350 : {
351 : SAL_WARN( "unotools.i18n", "getDays: Exception caught " << e.Message );
352 : }
353 0 : return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
354 : }
355 :
356 508 : OUString CalendarWrapper::getDisplayName( sal_Int16 nCalendarDisplayIndex, sal_Int16 nIdx, sal_Int16 nNameType ) const
357 : {
358 : try
359 : {
360 508 : if ( xC.is() )
361 508 : return xC->getDisplayName( nCalendarDisplayIndex, nIdx, nNameType );
362 : }
363 0 : catch (const Exception& e)
364 : {
365 : SAL_WARN( "unotools.i18n", "getDisplayName: Exception caught " << e.Message );
366 : }
367 0 : return OUString();
368 : }
369 :
370 : // --- XExtendedCalendar -----------------------------------------------------
371 :
372 5250 : OUString CalendarWrapper::getDisplayString( sal_Int32 nCalendarDisplayCode, sal_Int16 nNativeNumberMode ) const
373 : {
374 : try
375 : {
376 5250 : if ( xC.is() )
377 5250 : return xC->getDisplayString( nCalendarDisplayCode, nNativeNumberMode );
378 : }
379 0 : catch (const Exception& e)
380 : {
381 : SAL_WARN( "unotools.i18n", "getDisplayString: Exception caught " << e.Message );
382 : }
383 0 : return OUString();
384 : }
385 :
386 : // --- XCalendar3 ------------------------------------------------------------
387 :
388 0 : ::com::sun::star::i18n::Calendar2 CalendarWrapper::getLoadedCalendar() const
389 : {
390 : try
391 : {
392 0 : if ( xC.is() )
393 0 : return xC->getLoadedCalendar2();
394 : }
395 0 : catch (const Exception& e)
396 : {
397 : SAL_WARN( "unotools.i18n", "getLoadedCalendar2: Exception caught " << e.Message );
398 : }
399 0 : return ::com::sun::star::i18n::Calendar2();
400 : }
401 :
402 1106 : ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getGenitiveMonths() const
403 : {
404 : try
405 : {
406 1106 : if ( xC.is() )
407 1106 : return xC->getGenitiveMonths2();
408 : }
409 0 : catch (const Exception& e)
410 : {
411 : SAL_WARN( "unotools.i18n", "getGenitiveMonths: Exception caught " << e.Message );
412 : }
413 0 : return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
414 : }
415 :
416 1106 : ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getPartitiveMonths() const
417 : {
418 : try
419 : {
420 1106 : if ( xC.is() )
421 1106 : return xC->getPartitiveMonths2();
422 : }
423 0 : catch (const Exception& e)
424 : {
425 : SAL_WARN( "unotools.i18n", "getPartitiveMonths: Exception caught " << e.Message );
426 : }
427 0 : return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
428 : }
429 :
430 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|