diff options
author | Eric Erhardt <eric.erhardt@microsoft.com> | 2016-01-27 17:41:14 -0600 |
---|---|---|
committer | Eric Erhardt <eric.erhardt@microsoft.com> | 2016-02-02 09:42:29 -0600 |
commit | 8e7431e51cd088e58fb5e48dcd6615b86b479ca6 (patch) | |
tree | 3c26a217b765e784bfb15f1a0481d189ea12cf23 /src/corefx | |
parent | d876143bc87775b6c38eac4312cfc2dcbe5c0f3a (diff) | |
download | coreclr-8e7431e51cd088e58fb5e48dcd6615b86b479ca6.tar.gz coreclr-8e7431e51cd088e58fb5e48dcd6615b86b479ca6.tar.bz2 coreclr-8e7431e51cd088e58fb5e48dcd6615b86b479ca6.zip |
TimeZoneInfo.DisplayName values are not localized on Linux
Fixed by calling ICU's ucal_getTimeZoneDisplayName to read the display names for the current locale.
Fix https://github.com/dotnet/corefx/issues/2748
Diffstat (limited to 'src/corefx')
-rw-r--r-- | src/corefx/System.Globalization.Native/calendarData.cpp | 52 | ||||
-rw-r--r-- | src/corefx/System.Globalization.Native/errors.h | 36 | ||||
-rw-r--r-- | src/corefx/System.Globalization.Native/timeZoneInfo.cpp | 41 |
3 files changed, 84 insertions, 45 deletions
diff --git a/src/corefx/System.Globalization.Native/calendarData.cpp b/src/corefx/System.Globalization.Native/calendarData.cpp index fb035a9692..f91cc0cb57 100644 --- a/src/corefx/System.Globalization.Native/calendarData.cpp +++ b/src/corefx/System.Globalization.Native/calendarData.cpp @@ -9,6 +9,7 @@ #include "config.h" #include "locale.hpp" #include "holders.h" +#include "errors.h" #define GREGORIAN_NAME "gregorian" #define JAPANESE_NAME "japanese" @@ -82,43 +83,11 @@ enum CalendarDataType : int32_t AbbrevEraNames = 14, }; -/* -* These values should be kept in sync with -* System.Globalization.CalendarDataResult -*/ -enum CalendarDataResult : int32_t -{ - Success = 0, - UnknownError = 1, - InsufficentBuffer = 2, -}; - // the function pointer definition for the callback used in EnumCalendarInfo typedef void (*EnumCalendarInfoCallback)(const UChar*, const void*); /* Function: -GetCalendarDataResult - -Converts a UErrorCode to a CalendarDataResult. -*/ -CalendarDataResult GetCalendarDataResult(UErrorCode err) -{ - if (U_SUCCESS(err)) - { - return Success; - } - - if (err == U_BUFFER_OVERFLOW_ERROR) - { - return InsufficentBuffer; - } - - return UnknownError; -} - -/* -Function: GetCalendarName Gets the associated ICU calendar name for the CalendarId. @@ -247,18 +216,18 @@ GetMonthDayPattern Gets the Month-Day DateTime pattern for the specified locale. */ -CalendarDataResult GetMonthDayPattern(const char* locale, UChar* sMonthDay, int32_t stringCapacity) +ResultCode GetMonthDayPattern(const char* locale, UChar* sMonthDay, int32_t stringCapacity) { UErrorCode err = U_ZERO_ERROR; UDateTimePatternGenerator* pGenerator = udatpg_open(locale, &err); UDateTimePatternGeneratorHolder generatorHolder(pGenerator, err); if (U_FAILURE(err)) - return GetCalendarDataResult(err); + return GetResultCode(err); udatpg_getBestPattern(pGenerator, UDAT_MONTH_DAY_UCHAR, -1, sMonthDay, stringCapacity, &err); - return GetCalendarDataResult(err); + return GetResultCode(err); } /* @@ -267,8 +236,7 @@ GetNativeCalendarName Gets the native calendar name. */ -CalendarDataResult -GetNativeCalendarName(const char* locale, CalendarId calendarId, UChar* nativeName, int32_t stringCapacity) +ResultCode GetNativeCalendarName(const char* locale, CalendarId calendarId, UChar* nativeName, int32_t stringCapacity) { UErrorCode err = U_ZERO_ERROR; ULocaleDisplayNames* pDisplayNames = uldn_open(locale, ULDN_STANDARD_NAMES, &err); @@ -276,7 +244,7 @@ GetNativeCalendarName(const char* locale, CalendarId calendarId, UChar* nativeNa uldn_keyValueDisplayName(pDisplayNames, "calendar", GetCalendarName(calendarId), nativeName, stringCapacity, &err); - return GetCalendarDataResult(err); + return GetResultCode(err); } /* @@ -286,7 +254,7 @@ GetCalendarInfo Gets a single string of calendar information by filling the result parameter with the requested value. */ -extern "C" CalendarDataResult GlobalizationNative_GetCalendarInfo( +extern "C" ResultCode GlobalizationNative_GetCalendarInfo( const UChar* localeName, CalendarId calendarId, CalendarDataType dataType, UChar* result, int32_t resultCapacity) { UErrorCode err = U_ZERO_ERROR; @@ -542,9 +510,9 @@ The context parameter is passed through to the callback along with each string. */ extern "C" int32_t GlobalizationNative_EnumCalendarInfo( EnumCalendarInfoCallback callback, - const UChar* localeName, - CalendarId calendarId, - CalendarDataType dataType, + const UChar* localeName, + CalendarId calendarId, + CalendarDataType dataType, const void* context) { UErrorCode err = U_ZERO_ERROR; diff --git a/src/corefx/System.Globalization.Native/errors.h b/src/corefx/System.Globalization.Native/errors.h new file mode 100644 index 0000000000..2bfbdb2ba1 --- /dev/null +++ b/src/corefx/System.Globalization.Native/errors.h @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#pragma once + +#include <unicode/utypes.h> + +/* +* These values should be kept in sync with +* Interop.GlobalizationInterop.ResultCode +*/ +enum ResultCode : int32_t +{ + Success = 0, + UnknownError = 1, + InsufficentBuffer = 2, +}; + +/* +Converts a UErrorCode to a ResultCode. +*/ +static ResultCode GetResultCode(UErrorCode err) +{ + if (err == U_BUFFER_OVERFLOW_ERROR || err == U_STRING_NOT_TERMINATED_WARNING) + { + return InsufficentBuffer; + } + + if (U_SUCCESS(err)) + { + return Success; + } + + return UnknownError; +} diff --git a/src/corefx/System.Globalization.Native/timeZoneInfo.cpp b/src/corefx/System.Globalization.Native/timeZoneInfo.cpp index 025bccdb09..d0e01e5ce6 100644 --- a/src/corefx/System.Globalization.Native/timeZoneInfo.cpp +++ b/src/corefx/System.Globalization.Native/timeZoneInfo.cpp @@ -5,11 +5,13 @@ #include <stdint.h> #include <unistd.h> +#include <unicode/ucal.h> -/* -Function: -ReadLink +#include "locale.hpp" +#include "holders.h" +#include "errors.h" +/* Gets the symlink value for the path. */ extern "C" int32_t GlobalizationNative_ReadLink(const char* path, char* result, size_t resultCapacity) @@ -22,3 +24,36 @@ extern "C" int32_t GlobalizationNative_ReadLink(const char* path, char* result, result[r] = '\0'; return true; } + +/* +These values should be kept in sync with the managed Interop.GlobalizationInterop.TimeZoneDisplayNameType enum. +*/ +enum TimeZoneDisplayNameType : int32_t +{ + Generic = 0, + Standard = 1, + DaylightSavings = 2, +}; + +/* +Gets the localized display name for the specified time zone. +*/ +extern "C" ResultCode GlobalizationNative_GetTimeZoneDisplayName( + const UChar* localeName, const UChar* timeZoneId, TimeZoneDisplayNameType type, UChar* result, int32_t resultLength) +{ + UErrorCode err = U_ZERO_ERROR; + char locale[ULOC_FULLNAME_CAPACITY]; + GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, false, &err); + + int32_t timeZoneIdLength = -1; // timeZoneId is NULL-terminated + UCalendar* calendar = ucal_open(timeZoneId, timeZoneIdLength, locale, UCAL_DEFAULT, &err); + UCalendarHolder calendarHolder(calendar, err); + + // TODO (https://github.com/dotnet/corefx/issues/5741): need to support Generic names, but ICU "C" api + // has no public option for this. For now, just use the ICU standard name for both Standard and Generic + // (which is the same behavior on Windows with the mincore TIME_ZONE_INFORMATION APIs). + ucal_getTimeZoneDisplayName( + calendar, type == DaylightSavings ? UCAL_DST : UCAL_STANDARD, locale, result, resultLength, &err); + + return GetResultCode(err); +} |