[Libreoffice-commits] core.git: 2 commits - i18npool/inc i18npool/source svl/qa

Eike Rathke erack at redhat.com
Tue Jul 26 21:20:36 UTC 2016


 i18npool/inc/calendar_gregorian.hxx             |    3 
 i18npool/source/calendar/calendar_gregorian.cxx |  247 ------------------------
 svl/qa/unit/svl.cxx                             |   11 -
 3 files changed, 7 insertions(+), 254 deletions(-)

New commits:
commit 157b56a049a9a5f868d1f3b9856a631a40043a14
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Jul 26 23:19:48 2016 +0200

    activate the remaining 1945-04-02 test cases, tdf#100046
    
    Change-Id: I4d2f3d5602b162924c14348c0307a74ddeb93079

diff --git a/svl/qa/unit/svl.cxx b/svl/qa/unit/svl.cxx
index 72c0c13..4522516 100644
--- a/svl/qa/unit/svl.cxx
+++ b/svl/qa/unit/svl.cxx
@@ -497,14 +497,6 @@ void Test::testDateInput()
         { "US/Mountain", "1790-07-26" },
         { "Asia/Tehran", "1999-03-22" },
 
-        /* FIXME: still failing, see
-         * https://bugs.documentfoundation.org/show_bug.cgi?id=100046#c7 */
-#if 0
-        { "Europe/Gibraltar", "1945-04-02" },
-        { "Europe/Monaco", "1945-04-02" },
-        { "Europe/Paris", "1945-04-02" },
-#endif
-
         // Data from https://bugs.documentfoundation.org/show_bug.cgi?id=63230
         // https://bugs.documentfoundation.org/attachment.cgi?id=79051
         // https://bugs.documentfoundation.org/show_bug.cgi?id=79663
@@ -883,6 +875,7 @@ void Test::testDateInput()
         { "Europe/Gibraltar", "1942-04-05" },
         { "Europe/Gibraltar", "1943-04-04" },
         { "Europe/Gibraltar", "1944-04-02" },
+        { "Europe/Gibraltar", "1945-04-02" },
         { "Europe/Gibraltar", "1947-04-13" },
         { "Europe/Helsinki", "1921-05-01" },
         { "Europe/Istanbul", "1880-01-01" },
@@ -908,12 +901,14 @@ void Test::testDateInput()
         { "Europe/Monaco", "1942-03-09" },
         { "Europe/Monaco", "1943-03-29" },
         { "Europe/Monaco", "1944-04-03" },
+        { "Europe/Monaco", "1945-04-02" },
         { "Europe/Moscow", "1916-07-03" },
         { "Europe/Moscow", "1919-05-31" },
         { "Europe/Moscow", "1930-06-21" },
         { "Europe/Moscow", "1992-01-19" },
         { "Europe/Moscow", "2011-03-27" },
         { "Europe/Oslo", "1895-01-01" },
+        { "Europe/Paris", "1945-04-02" },
         { "Europe/Prague", "1891-10-01" },
         { "Europe/Riga", "1926-05-11" },
         { "Europe/Riga", "1940-08-05" },
commit 8e91b0177cbf6554acf7ccfbcc573f647e7fcf4d
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Jul 26 23:18:30 2016 +0200

    Resolves: tdf#100046 the dreaded 1945-04-02 Double DST, also tdf#79663
    
    A coward not having changed this earlier, partially taken from a patch that was
    submitted for tdf#79663 but broke API, thanks to Isamu Mogi again.
    
    This removes all the clutter around timezone and DST correction that was
    necessary for early ICU versions, which apparently gets things right now and
    the clutter can still be confused by corner cases.
    
    Change-Id: I9a90f933e8db8c6e0db145520ebf71cc27621abc

diff --git a/i18npool/inc/calendar_gregorian.hxx b/i18npool/inc/calendar_gregorian.hxx
index 4a16c00..283e1b7 100644
--- a/i18npool/inc/calendar_gregorian.hxx
+++ b/i18npool/inc/calendar_gregorian.hxx
@@ -116,9 +116,6 @@ private:
 
     /** Submit fieldSetValue array according to fieldSet. */
     void submitFields() throw(css::uno::RuntimeException);
-    /** Submit fieldSetValue array according to fieldSet, plus EYMDhms if >=0,
-        plus zone and DST if != 0 */
-    void submitValues( sal_Int32 nEra, sal_Int32 nYear, sal_Int32 nMonth, sal_Int32 nDay, sal_Int32 nHour, sal_Int32 nMinute, sal_Int32 nSecond, sal_Int32 nMilliSecond, sal_Int32 nZone, sal_Int32 nDST) throw(css::uno::RuntimeException);
     /** Set fields internally. */
     void setValue() throw(css::uno::RuntimeException);
     /** Obtain combined field values for timezone offset (minutes+secondmillis)
diff --git a/i18npool/source/calendar/calendar_gregorian.cxx b/i18npool/source/calendar/calendar_gregorian.cxx
index 275b24d..f3fa8ea 100644
--- a/i18npool/source/calendar/calendar_gregorian.cxx
+++ b/i18npool/source/calendar/calendar_gregorian.cxx
@@ -491,260 +491,21 @@ void Calendar_gregorian::submitFields() throw(css::uno::RuntimeException)
         body->set( fieldNameConverter( CalendarFieldIndex::DST_OFFSET), nDSTOffset);
 }
 
-void Calendar_gregorian::submitValues( sal_Int32 nEra, sal_Int32 nYear,
-        sal_Int32 nMonth, sal_Int32 nDay, sal_Int32 nHour, sal_Int32 nMinute,
-        sal_Int32 nSecond, sal_Int32 nMilliSecond, sal_Int32 nZone, sal_Int32 nDST )
-            throw(css::uno::RuntimeException)
-{
-    submitFields();
-    if (nEra >= 0)
-        body->set( UCAL_ERA, nEra);
-    if (nYear >= 0)
-        body->set( UCAL_YEAR, nYear);
-    if (nMonth >= 0)
-        body->set( UCAL_MONTH, nMonth);
-    if (nDay >= 0)
-        body->set( UCAL_DATE, nDay);
-    if (nHour >= 0)
-        body->set( UCAL_HOUR_OF_DAY, nHour);
-    if (nMinute >= 0)
-        body->set( UCAL_MINUTE, nMinute);
-    if (nSecond >= 0)
-        body->set( UCAL_SECOND, nSecond);
-    if (nMilliSecond >= 0)
-        body->set( UCAL_MILLISECOND, nMilliSecond);
-    if (nZone != 0)
-        body->set( UCAL_ZONE_OFFSET, nZone);
-    if (nDST != 0)
-        body->set( UCAL_DST_OFFSET, nDST);
-}
-
-static void lcl_setCombinedOffsetFieldValues( sal_Int32 nValue,
-        sal_Int16 rFieldSetValue[], sal_Int16 rFieldValue[],
-        sal_Int16 nParentFieldIndex, sal_Int16 nChildFieldIndex )
-{
-    sal_Int32 nTrunc = nValue / 60000;
-    rFieldSetValue[nParentFieldIndex] = rFieldValue[nParentFieldIndex] =
-        static_cast<sal_Int16>( nTrunc);
-    sal_uInt16 nMillis = static_cast<sal_uInt16>( abs( nValue - nTrunc * 60000));
-    rFieldSetValue[nChildFieldIndex] = rFieldValue[nChildFieldIndex] =
-        static_cast<sal_Int16>( nMillis);
-}
-
 void Calendar_gregorian::setValue() throw(RuntimeException)
 {
-    // Correct DST glitch, see also localtime/gmtime conversion pitfalls at
-    // http://www.erack.de/download/timetest.c
-
-    // #i24082# in order to make the DST correction work in all
-    // circumstances, the time values have to be always resubmitted,
-    // regardless whether specified by the caller or not. It is not
-    // sufficient to rely on the ICU internal values previously set, as the
-    // following may happen:
-    // - Let 2004-03-28T02:00 be the onsetRule.
-    // - On 2004-03-29 (calendar initialized with 2004-03-29T00:00 DST) set
-    //   a date of 2004-03-28 => calendar results in 2004-03-27T23:00 no DST.
-    // - Correcting this with simply "2004-03-28 no DST" and no time
-    //   specified results in 2004-03-29T00:00, the ICU internal 23:00 time
-    //   being adjusted to 24:00 in this case, switching one day further.
-    // => submit 2004-03-28T00:00 no DST.
-
-    // This got even weirder since ICU incorporated also historical data,
-    // even the timezone may differ for different dates! It is necessary to
-    // let ICU choose the corresponding OlsonTimeZone transitions and adapt
-    // values.
-    // #i86094# gives examples where that went wrong:
-    // TZ=Europe/Moscow date <= 1919-07-01
-    //      zone +2:30:48 (!) instead of +3h, DST +2h instead of +1h
-    // TZ=America/St_Johns date <= 1935-03-30
-    //      zone -3:30:52 (!) instead of -3:30
-
     // Copy fields before calling submitFields() directly or indirectly below.
     memcpy(fieldSetValue, fieldValue, sizeof(fieldSetValue));
     // Possibly setup ERA and YEAR in fieldSetValue.
     mapToGregorian();
 
-    DUMP_ICU_CAL_MSG(("%s\n","setValue() before any submission"));
-    DUMP_I18N_CAL_MSG(("%s\n","setValue() before any submission"));
-
-    bool bNeedZone = !(fieldSet & (1 << CalendarFieldIndex::ZONE_OFFSET));
-    bool bNeedDST  = !(fieldSet & (1 << CalendarFieldIndex::DST_OFFSET));
-    sal_Int32 nZone1, nDST1, nEra, nYear, nMonth, nDay, nHour, nMinute, nSecond, nMilliSecond, nZone0, nDST0;
-    nZone1 = nDST1 = nZone0 = nDST0 = 0;
-    nEra = nYear = nMonth = nDay = nHour = nMinute = nSecond = nMilliSecond = -1;
-    if ( bNeedZone || bNeedDST )
-    {
-        UErrorCode status;
-        if ( !(fieldSet & (1 << CalendarFieldIndex::ERA)) )
-        {
-            nEra = body->get( UCAL_ERA, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nEra = -1;
-        }
-        if ( !(fieldSet & (1 << CalendarFieldIndex::YEAR)) )
-        {
-            nYear = body->get( UCAL_YEAR, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nYear = -1;
-        }
-        if ( !(fieldSet & (1 << CalendarFieldIndex::MONTH)) )
-        {
-            nMonth = body->get( UCAL_MONTH, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nMonth = -1;
-        }
-        if ( !(fieldSet & (1 << CalendarFieldIndex::DAY_OF_MONTH)) )
-        {
-            nDay = body->get( UCAL_DATE, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nDay = -1;
-        }
-        if ( !(fieldSet & (1 << CalendarFieldIndex::HOUR)) )
-        {
-            nHour = body->get( UCAL_HOUR_OF_DAY, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nHour = -1;
-        }
-        if ( !(fieldSet & (1 << CalendarFieldIndex::MINUTE)) )
-        {
-            nMinute = body->get( UCAL_MINUTE, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nMinute = -1;
-        }
-        if ( !(fieldSet & (1 << CalendarFieldIndex::SECOND)) )
-        {
-            nSecond = body->get( UCAL_SECOND, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nSecond = -1;
-        }
-        if ( !(fieldSet & (1 << CalendarFieldIndex::MILLISECOND)) )
-        {
-            nMilliSecond = body->get( UCAL_MILLISECOND, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nMilliSecond = -1;
-        }
-        if ( !(fieldSet & (1 << CalendarFieldIndex::ZONE_OFFSET)) )
-        {
-            nZone0 = body->get( UCAL_ZONE_OFFSET, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nZone0 = 0;
-        }
-        if ( !(fieldSet & (1 << CalendarFieldIndex::DST_OFFSET)) )
-        {
-            nDST0 = body->get( UCAL_DST_OFFSET, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nDST0 = 0;
-        }
-
-        // Submit values to obtain a time zone and DST corresponding to the date/time.
-        submitValues( nEra, nYear, nMonth, nDay, nHour, nMinute, nSecond, nMilliSecond, nZone0, nDST0);
-
-        DUMP_ICU_CAL_MSG(("%s\n","setValue() in bNeedZone||bNeedDST after submitValues()"));
-        DUMP_I18N_CAL_MSG(("%s\n","setValue() in bNeedZone||bNeedDST after submitValues()"));
-        nZone1 = body->get( UCAL_ZONE_OFFSET, status = U_ZERO_ERROR);
-        if ( !U_SUCCESS(status) )
-            nZone1 = 0;
-        nDST1 = body->get( UCAL_DST_OFFSET, status = U_ZERO_ERROR);
-        if ( !U_SUCCESS(status) )
-            nDST1 = 0;
-    }
+    DUMP_ICU_CAL_MSG(("%s\n","setValue() before submission"));
+    DUMP_I18N_CAL_MSG(("%s\n","setValue() before submission"));
 
-    // The original submission, may lead to a different zone/DST and
-    // different date.
     submitFields();
-    DUMP_ICU_CAL_MSG(("%s\n","setValue() after original submission"));
-    DUMP_I18N_CAL_MSG(("%s\n","setValue() after original submission"));
 
-    if ( bNeedZone || bNeedDST )
-    {
-        UErrorCode status;
-        sal_Int32 nZone2 = body->get( UCAL_ZONE_OFFSET, status = U_ZERO_ERROR);
-        if ( !U_SUCCESS(status) )
-            nZone2 = nZone1;
-        sal_Int32 nDST2 = body->get( UCAL_DST_OFFSET, status = U_ZERO_ERROR);
-        if ( !U_SUCCESS(status) )
-            nDST2 = nDST1;
-        if ( nZone0 != nZone1 || nZone2 != nZone1 || nDST0 != nDST1 || nDST2 != nDST1 )
-        {
-            // Due to different DSTs, resulting date values may differ if
-            // DST is onset at 00:00 and the very onsetRule date was
-            // submitted with DST off => date-1 23:00, for example, which
-            // is not what we want.
-            // Resubmit all values, this time including DST => date 01:00
-            // Similar for zone differences.
-            // If already the first full submission with nZone0 and nDST0
-            // lead to date-1 23:00, the original submission was based on
-            // that date if it wasn't a full date (nDST0 set, nDST1 not
-            // set, nDST2==nDST1). If it was January 1st without year we're
-            // even off by one year now. Resubmit all values including new
-            // DST => date 00:00.
-
-            // Set field values accordingly in case they were used.
-            if (!bNeedZone)
-                lcl_setCombinedOffsetFieldValues( nZone2, fieldSetValue,
-                        fieldValue, CalendarFieldIndex::ZONE_OFFSET,
-                        CalendarFieldIndex::ZONE_OFFSET_SECOND_MILLIS);
-            if (!bNeedDST)
-                lcl_setCombinedOffsetFieldValues( nDST2, fieldSetValue,
-                        fieldValue, CalendarFieldIndex::DST_OFFSET,
-                        CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS);
-            submitValues( nEra, nYear, nMonth, nDay, nHour, nMinute, nSecond, nMilliSecond, nZone2, nDST2);
-            DUMP_ICU_CAL_MSG(("%s\n","setValue() after Zone/DST glitch resubmit"));
-            DUMP_I18N_CAL_MSG(("%s\n","setValue() after Zone/DST glitch resubmit"));
-
-            // Time zone transition => resubmit.
-            // TZ=America/St_Johns date <= 1935-03-30
-            //      -3:30:52 (!) instead of -3:30
-            //      if first submission included time zone -3:30 that would be wrong.
-            bool bResubmit = false;
-            sal_Int32 nZone3 = body->get( UCAL_ZONE_OFFSET, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nZone3 = nZone2;
-            if (nZone3 != nZone2)
-            {
-                bResubmit = true;
-                if (!bNeedZone)
-                    lcl_setCombinedOffsetFieldValues( nZone3, fieldSetValue,
-                            fieldValue, CalendarFieldIndex::ZONE_OFFSET,
-                            CalendarFieldIndex::ZONE_OFFSET_SECOND_MILLIS);
-            }
+    DUMP_ICU_CAL_MSG(("%s\n","setValue() after submission"));
+    DUMP_I18N_CAL_MSG(("%s\n","setValue() after submission"));
 
-            // 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.
-            // It doesn't even have to be on an onsetDay as the DST is
-            // factored in all days by ICU and there seems to be some
-            // unknown behavior.
-            // TZ=Asia/Tehran 1999-03-22 exposes this, for example.
-            sal_Int32 nDST3 = body->get( UCAL_DST_OFFSET, status = U_ZERO_ERROR);
-            if ( !U_SUCCESS(status) )
-                nDST3 = nDST2;
-            if (nDST2 != nDST3 && !nDST3)
-            {
-                bResubmit = true;
-                if (!bNeedDST)
-                {
-                    fieldSetValue[CalendarFieldIndex::DST_OFFSET] =
-                        fieldValue[CalendarFieldIndex::DST_OFFSET] = 0;
-                    fieldSetValue[CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS] =
-                        fieldValue[CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS] = 0;
-                }
-            }
-            if (bResubmit)
-            {
-                submitValues( nEra, nYear, nMonth, nDay, nHour, nMinute, nSecond, nMilliSecond, nZone3, nDST3);
-                DUMP_ICU_CAL_MSG(("%s\n","setValue() after Zone/DST glitch 2nd resubmit"));
-                DUMP_I18N_CAL_MSG(("%s\n","setValue() after Zone/DST glitch 2nd resubmit"));
-            }
-            SAL_INFO( "i18npool", "Calendar_gregorian::setValue:"
-                    "  nZone0 " << nZone0 << ", nDST0 " << nDST0 <<
-                    ", nZone1 " << nZone1 << ", nDST1 " << nDST1 <<
-                    ", nZone2 " << nZone2 << ", nDST2 " << nDST2 <<
-                    ", nZone3 " << nZone3 << ", nDST3 " << nDST3);
-        }
-    }
 #if erDUMP_ICU_CALENDAR || erDUMP_I18N_CALENDAR
     {
         // force icu::Calendar to recalculate


More information about the Libreoffice-commits mailing list