diff options
author | Eike Rathke <erack@redhat.com> | 2019-06-19 23:03:49 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2019-06-20 11:27:20 +0200 |
commit | a9c02d543987a0c05beda19905ccd6fb4263b592 (patch) | |
tree | 9a9d974383787f937196a974446402bc9fe04068 /i18npool/source/calendar/calendar_gregorian.cxx | |
parent | InvalidateWindow should be preferred (diff) | |
download | core-a9c02d543987a0c05beda19905ccd6fb4263b592.tar.gz core-a9c02d543987a0c05beda19905ccd6fb4263b592.zip |
Resolves: tdf#92503 introduce TimeZone to calendar loading and default to UTC
Without that, the system's time zone was used which on DST
transition dates leads to non-existent times when switching
to/from DST. As the calendar use and number parser/formatter nor
conversions or calculations are time zone aware, using not DST
afflicted UTC is the better choice.
Change-Id: I3303c6620d8c4b9d081555c8293954fb1bd67895
Reviewed-on: https://gerrit.libreoffice.org/74386
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
(cherry picked from commit 942de6a01ba990e5f3bc55ce4ab3737a03f67f39)
Reviewed-on: https://gerrit.libreoffice.org/74399
Diffstat (limited to 'i18npool/source/calendar/calendar_gregorian.cxx')
-rw-r--r-- | i18npool/source/calendar/calendar_gregorian.cxx | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/i18npool/source/calendar/calendar_gregorian.cxx b/i18npool/source/calendar/calendar_gregorian.cxx index 18676361027a..f3b228efc04e 100644 --- a/i18npool/source/calendar/calendar_gregorian.cxx +++ b/i18npool/source/calendar/calendar_gregorian.cxx @@ -167,6 +167,11 @@ Calendar_gregorian::init(const Era *_eraArray) * */ icu::Locale aIcuLocale( "", nullptr, nullptr, "calendar=gregorian"); + /* XXX: not specifying a timezone when creating a calendar assigns the + * system's timezone with all DST quirks, invalid times when switching + * to/from DST and so on. The XCalendar* interfaces are defined to support + * local time and UTC time so we can not override that here. + */ UErrorCode status = U_ZERO_ERROR; body.reset( icu::Calendar::createInstance( aIcuLocale, status) ); if (!body || !U_SUCCESS(status)) throw ERROR; @@ -369,6 +374,22 @@ Calendar_gregorian::getLocalDateTime() return (fTime + (nZoneOffset + nDSTOffset)) / U_MILLIS_PER_DAY; } +bool Calendar_gregorian::setTimeZone( const OUString& rTimeZone ) +{ + if (fieldSet) + { + setValue(); + getValue(); + } + const icu::UnicodeString aID( reinterpret_cast<const UChar*>(rTimeZone.getStr()), rTimeZone.getLength()); + const std::unique_ptr<const icu::TimeZone> pTZ( icu::TimeZone::createTimeZone(aID)); + if (!pTZ) + return false; + + body->setTimeZone(*pTZ); + return true; +} + // map field value from gregorian calendar to other calendar, it can be overwritten by derived class. // By using eraArray, it can take care Japanese and Taiwan ROC calendar. void Calendar_gregorian::mapFromGregorian() |