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