update credits
[LibreOffice.git] / unotools / source / i18n / calendarwrapper.cxx
blob700a8d0d8500edf90c27150f16a35e53fd3ec1b0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <rtl/strbuf.hxx>
22 #include <tools/string.hxx>
23 #include <tools/debug.hxx>
24 #include <unotools/calendarwrapper.hxx>
25 #include <com/sun/star/i18n/CalendarFieldIndex.hpp>
26 #include <com/sun/star/i18n/LocaleCalendar.hpp>
28 using namespace ::com::sun::star;
29 using namespace ::com::sun::star::i18n;
30 using namespace ::com::sun::star::uno;
33 const double MILLISECONDS_PER_DAY = 1000.0 * 60.0 * 60.0 * 24.0;
36 CalendarWrapper::CalendarWrapper(
37 const Reference< uno::XComponentContext > & rxContext
40 aEpochStart( Date( 1, 1, 1970 ) )
42 xC = LocaleCalendar::create(rxContext);
45 CalendarWrapper::~CalendarWrapper()
50 void CalendarWrapper::loadDefaultCalendar( const ::com::sun::star::lang::Locale& rLocale )
52 try
54 if ( xC.is() )
55 xC->loadDefaultCalendar( rLocale );
57 catch (const Exception& e)
59 SAL_WARN( "unotools.i18n", "loadDefaultCalendar: Exception caught " << e.Message );
64 void CalendarWrapper::loadCalendar( const OUString& rUniqueID, const ::com::sun::star::lang::Locale& rLocale )
66 try
68 if ( xC.is() )
69 xC->loadCalendar( rUniqueID, rLocale );
71 catch (const Exception& e)
73 SAL_WARN( "unotools.i18n", "loadCalendar: Exception caught requested: "
74 << rUniqueID << " Locale: " << rLocale.Language << "_" << rLocale.Country << " " << e.Message );
79 ::com::sun::star::uno::Sequence< OUString > CalendarWrapper::getAllCalendars( const ::com::sun::star::lang::Locale& rLocale ) const
81 try
83 if ( xC.is() )
84 return xC->getAllCalendars( rLocale );
86 catch (const Exception& e)
88 SAL_WARN( "unotools.i18n", "getAllCalendars: Exception caught " << e.Message );
91 return ::com::sun::star::uno::Sequence< OUString > (0);
95 OUString CalendarWrapper::getUniqueID() const
97 try
99 if ( xC.is() )
100 return xC->getUniqueID();
102 catch (const Exception& e)
104 SAL_WARN( "unotools.i18n", "getUniqueID: Exception caught " << e.Message );
106 return OUString();
110 void CalendarWrapper::setDateTime( double nTimeInDays )
114 if ( xC.is() )
115 xC->setDateTime( nTimeInDays );
117 catch (const Exception& e)
119 SAL_WARN( "unotools.i18n", "setDateTime: Exception caught " << e.Message );
124 double CalendarWrapper::getDateTime() const
128 if ( xC.is() )
129 return xC->getDateTime();
131 catch (const Exception& e)
133 SAL_WARN( "unotools.i18n", "getDateTime: Exception caught " << e.Message );
135 return 0.0;
139 sal_Int32 CalendarWrapper::getCombinedOffsetInMillis(
140 sal_Int16 nParentFieldIndex, sal_Int16 nChildFieldIndex ) const
142 sal_Int32 nOffset = 0;
145 if ( xC.is() )
147 nOffset = static_cast<sal_Int32>( xC->getValue( nParentFieldIndex )) * 60000;
148 sal_Int16 nSecondMillis = xC->getValue( nChildFieldIndex );
149 if (nOffset < 0)
150 nOffset -= static_cast<sal_uInt16>( nSecondMillis);
151 else
152 nOffset += static_cast<sal_uInt16>( nSecondMillis);
155 catch (const Exception& e)
157 SAL_WARN( "unotools.i18n", "setLocalDateTime: Exception caught " << e.Message );
159 return nOffset;
163 sal_Int32 CalendarWrapper::getZoneOffsetInMillis() const
165 return getCombinedOffsetInMillis( CalendarFieldIndex::ZONE_OFFSET,
166 CalendarFieldIndex::ZONE_OFFSET_SECOND_MILLIS);
170 sal_Int32 CalendarWrapper::getDSTOffsetInMillis() const
172 return getCombinedOffsetInMillis( CalendarFieldIndex::DST_OFFSET,
173 CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS);
177 void CalendarWrapper::setLocalDateTime( double nTimeInDays )
181 if ( xC.is() )
183 // First set a nearby value to obtain the timezone and DST offset.
184 // This is necessary to let ICU choose the corresponding
185 // OlsonTimeZone transitions. Since ICU incorporates also
186 // historical data even the timezone may differ for different
187 // dates! (Which was the cause for #i76623# when the timezone of a
188 // previously set date was used.) Timezone may also include
189 // seconds, so use milliseconds field as well.
190 xC->setDateTime( nTimeInDays );
191 sal_Int32 nZone1 = getZoneOffsetInMillis();
192 sal_Int32 nDST1 = getDSTOffsetInMillis();
193 double nLoc = nTimeInDays - (double)(nZone1 + nDST1) / MILLISECONDS_PER_DAY;
194 xC->setDateTime( nLoc );
195 sal_Int32 nZone2 = getZoneOffsetInMillis();
196 sal_Int32 nDST2 = getDSTOffsetInMillis();
197 // If DSTs differ after calculation, we crossed boundaries. Do it
198 // again, this time using the DST corrected initial value for the
199 // real local time.
200 // See also localtime/gmtime conversion pitfalls at
201 // http://www.erack.de/download/timetest.c
202 if ( nDST1 != nDST2 )
204 nLoc = nTimeInDays - (double)(nZone2 + nDST2) / MILLISECONDS_PER_DAY;
205 xC->setDateTime( nLoc );
206 // #i17222# If the DST onset rule says to switch from 00:00 to
207 // 01:00 and we tried to set onsetDay 00:00 with DST, the
208 // result was onsetDay-1 23:00 and no DST, which is not what we
209 // want. So once again without DST, resulting in onsetDay
210 // 01:00 and DST. Yes, this seems to be weird, but logically
211 // correct.
212 sal_Int32 nDST3 = getDSTOffsetInMillis();
213 if ( nDST2 != nDST3 && !nDST3 )
215 nLoc = nTimeInDays - (double)(nZone2 + nDST3) / MILLISECONDS_PER_DAY;
216 xC->setDateTime( nLoc );
221 catch (const Exception& e)
223 SAL_WARN( "unotools.i18n", "setLocalDateTime: Exception caught " << e.Message );
228 double CalendarWrapper::getLocalDateTime() const
232 if ( xC.is() )
234 double nTimeInDays = xC->getDateTime();
235 sal_Int32 nZone = getZoneOffsetInMillis();
236 sal_Int32 nDST = getDSTOffsetInMillis();
237 nTimeInDays += (double)(nZone + nDST) / MILLISECONDS_PER_DAY;
238 return nTimeInDays;
241 catch (const Exception& e)
243 SAL_WARN( "unotools.i18n", "getLocalDateTime: Exception caught " << e.Message );
245 return 0.0;
249 void CalendarWrapper::setValue( sal_Int16 nFieldIndex, sal_Int16 nValue )
253 if ( xC.is() )
254 xC->setValue( nFieldIndex, nValue );
256 catch (const Exception& e)
258 SAL_WARN( "unotools.i18n", "setValue: Exception caught " << e.Message );
263 sal_Bool CalendarWrapper::isValid() const
267 if ( xC.is() )
268 return xC->isValid();
270 catch (const Exception& e)
272 SAL_WARN( "unotools.i18n", "isValue: Exception caught " << e.Message );
274 return sal_False;
278 sal_Int16 CalendarWrapper::getValue( sal_Int16 nFieldIndex ) const
282 if ( xC.is() )
283 return xC->getValue( nFieldIndex );
285 catch (const Exception& e)
287 SAL_WARN( "unotools.i18n", "getValue: Exception caught " << e.Message );
289 return 0;
293 void CalendarWrapper::addValue( sal_Int16 nFieldIndex, sal_Int32 nAmount )
297 if ( xC.is() )
298 xC->addValue( nFieldIndex, nAmount );
300 catch (const Exception& e)
302 SAL_WARN( "unotools.i18n", "addValue: Exception caught " << e.Message );
307 sal_Int16 CalendarWrapper::getFirstDayOfWeek() const
311 if ( xC.is() )
312 return xC->getFirstDayOfWeek();
314 catch (const Exception& e)
316 SAL_WARN( "unotools.i18n", "getFirstDayOfWeek: Exception caught " << e.Message );
318 return 0;
322 sal_Int16 CalendarWrapper::getNumberOfMonthsInYear() const
326 if ( xC.is() )
327 return xC->getNumberOfMonthsInYear();
329 catch (const Exception& e)
331 SAL_WARN( "unotools.i18n", "getNumberOfMonthsInYear: Exception caught " << e.Message );
333 return 0;
337 sal_Int16 CalendarWrapper::getNumberOfDaysInWeek() const
341 if ( xC.is() )
342 return xC->getNumberOfDaysInWeek();
344 catch (const Exception& e)
346 SAL_WARN( "unotools.i18n", "getNumberOfDaysInWeek: Exception caught " << e.Message );
348 return 0;
352 ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getMonths() const
356 if ( xC.is() )
357 return xC->getMonths2();
359 catch (const Exception& e)
361 SAL_WARN( "unotools.i18n", "getMonths: Exception caught " << e.Message );
363 return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
367 ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getDays() const
371 if ( xC.is() )
372 return xC->getDays2();
374 catch (const Exception& e)
376 SAL_WARN( "unotools.i18n", "getDays: Exception caught " << e.Message );
378 return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
382 String CalendarWrapper::getDisplayName( sal_Int16 nCalendarDisplayIndex, sal_Int16 nIdx, sal_Int16 nNameType ) const
386 if ( xC.is() )
387 return xC->getDisplayName( nCalendarDisplayIndex, nIdx, nNameType );
389 catch (const Exception& e)
391 SAL_WARN( "unotools.i18n", "getDisplayName: Exception caught " << e.Message );
393 return String();
397 // --- XExtendedCalendar -----------------------------------------------------
399 String CalendarWrapper::getDisplayString( sal_Int32 nCalendarDisplayCode, sal_Int16 nNativeNumberMode ) const
403 if ( xC.is() )
404 return xC->getDisplayString( nCalendarDisplayCode, nNativeNumberMode );
406 catch (const Exception& e)
408 SAL_WARN( "unotools.i18n", "getDisplayString: Exception caught " << e.Message );
410 return String();
414 // --- XCalendar3 ------------------------------------------------------------
416 ::com::sun::star::i18n::Calendar2 CalendarWrapper::getLoadedCalendar() const
420 if ( xC.is() )
421 return xC->getLoadedCalendar2();
423 catch (const Exception& e)
425 SAL_WARN( "unotools.i18n", "getLoadedCalendar2: Exception caught " << e.Message );
427 return ::com::sun::star::i18n::Calendar2();
431 ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getGenitiveMonths() const
435 if ( xC.is() )
436 return xC->getGenitiveMonths2();
438 catch (const Exception& e)
440 SAL_WARN( "unotools.i18n", "getGenitiveMonths: Exception caught " << e.Message );
442 return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
446 ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getPartitiveMonths() const
450 if ( xC.is() )
451 return xC->getPartitiveMonths2();
453 catch (const Exception& e)
455 SAL_WARN( "unotools.i18n", "getPartitiveMonths: Exception caught " << e.Message );
457 return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
460 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */