use XCalendar4 local date/time in CalendarWrapper, tdf#63230
Replaces the three-step timezone+DST correction. Hopefully ICU does take these
into account, but this needs to be double-rechecked and if necessary
correction be implemented at XCalendar4::setLocalDateTime()
See also
http://userguide.icu-project.org/datetime/calendar#TOC-Ambiguous-Wall-Clock-Time-Resolution
Interpreting as standard time for non-existing times sounds like what we need
and covers the dreaded "00:00-01:00 doesn't exist" case that decremented the
day and was fixed here with the now removed workaround.
diff --git a/unotools/source/i18n/calendarwrapper.cxx b/unotools/source/i18n/calendarwrapper.cxx
index 6d082f2..27c1b47 100644
--- a/unotools/source/i18n/calendarwrapper.cxx
+++ b/unotools/source/i18n/calendarwrapper.cxx
@@ -165,42 +165,7 @@ void CalendarWrapper::setLocalDateTime( double fTimeInDays )
{
if ( xC.is() )
{
// First set a nearby value to obtain the timezone and DST offset.
// This is necessary to let ICU choose the corresponding
// OlsonTimeZone transitions. Since ICU incorporates also
// historical data even the timezone may differ for different
// dates! (Which was the cause for #i76623# when the timezone of a
// previously set date was used.) Timezone may also include
// seconds, so use milliseconds field as well.
xC->setDateTime( fTimeInDays );
sal_Int32 nZone1 = getZoneOffsetInMillis();
sal_Int32 nDST1 = getDSTOffsetInMillis();
double fLoc = fTimeInDays - (double)(nZone1 + nDST1) / MILLISECONDS_PER_DAY;
xC->setDateTime( fLoc );
sal_Int32 nZone2 = getZoneOffsetInMillis();
sal_Int32 nDST2 = getDSTOffsetInMillis();
// If DSTs differ after calculation, we crossed boundaries. Do it
// again, this time using the DST corrected initial value for the
// real local time.
// See also localtime/gmtime conversion pitfalls at
// http://www.erack.de/download/timetest.c
if ( nDST1 != nDST2 )
{
fLoc = fTimeInDays - (double)(nZone2 + nDST2) / MILLISECONDS_PER_DAY;
xC->setDateTime( fLoc );
// #i17222# If the DST onset rule says to switch from 00:00 to
// 01:00 and we tried to set onsetDay 00:00 with DST, the
// result was onsetDay-1 23:00 and no DST, which is not what we
// want. So once again without DST, resulting in onsetDay
// 01:00 and DST. Yes, this seems to be weird, but logically
// correct.
sal_Int32 nDST3 = getDSTOffsetInMillis();
if ( nDST2 != nDST3 && !nDST3 )
{
fLoc = fTimeInDays - (double)(nZone2 + nDST3) / MILLISECONDS_PER_DAY;
xC->setDateTime( fLoc );
}
}
xC->setLocalDateTime( fTimeInDays );
}
}
catch (const Exception& e)
@@ -215,11 +180,7 @@ double CalendarWrapper::getLocalDateTime() const
{
if ( xC.is() )
{
double fTimeInDays = xC->getDateTime();
sal_Int32 nZone = getZoneOffsetInMillis();
sal_Int32 nDST = getDSTOffsetInMillis();
fTimeInDays += (double)(nZone + nDST) / MILLISECONDS_PER_DAY;
return fTimeInDays;
return xC->getLocalDateTime();
}
}
catch (const Exception& e)