summaryrefslogtreecommitdiff
path: root/src/corefx
diff options
context:
space:
mode:
authorEric Erhardt <eric.erhardt@microsoft.com>2016-01-27 17:41:14 -0600
committerEric Erhardt <eric.erhardt@microsoft.com>2016-02-02 09:42:29 -0600
commit8e7431e51cd088e58fb5e48dcd6615b86b479ca6 (patch)
tree3c26a217b765e784bfb15f1a0481d189ea12cf23 /src/corefx
parentd876143bc87775b6c38eac4312cfc2dcbe5c0f3a (diff)
downloadcoreclr-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.cpp52
-rw-r--r--src/corefx/System.Globalization.Native/errors.h36
-rw-r--r--src/corefx/System.Globalization.Native/timeZoneInfo.cpp41
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);
+}