mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-12 00:14:25 +00:00
ICU-8892 merge into 4.8.x r32038 and r32039 from #9408
X-SVN-Rev: 33454
This commit is contained in:
parent
1097a8855c
commit
0e309abc9f
1 changed files with 91 additions and 8 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
********************************************************************************
|
||||
* Copyright (C) 2005-2011, International Business Machines
|
||||
* Copyright (C) 2005-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
********************************************************************************
|
||||
*
|
||||
|
@ -29,6 +29,8 @@
|
|||
# define NOMCX
|
||||
#include <windows.h>
|
||||
|
||||
#define MAX_LENGTH_ID 40
|
||||
|
||||
/* The layout of the Tzi value in the registry */
|
||||
typedef struct
|
||||
{
|
||||
|
@ -170,6 +172,28 @@ static LONG getTZI(const char *winid, TZI *tzi)
|
|||
return result;
|
||||
}
|
||||
|
||||
static LONG getSTDName(const char *winid, char *regStdName, int32_t length) {
|
||||
DWORD cbData = length;
|
||||
LONG result;
|
||||
HKEY hkey;
|
||||
|
||||
result = openTZRegKey(&hkey, winid);
|
||||
|
||||
if (result == ERROR_SUCCESS) {
|
||||
result = RegQueryValueExA(hkey,
|
||||
STD_REGKEY,
|
||||
NULL,
|
||||
NULL,
|
||||
(LPBYTE)regStdName,
|
||||
&cbData);
|
||||
|
||||
}
|
||||
|
||||
RegCloseKey(hkey);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
This code attempts to detect the Windows time zone, as set in the
|
||||
Windows Date and Time control panel. It attempts to work on
|
||||
|
@ -227,6 +251,15 @@ uprv_detectWindowsTimeZone() {
|
|||
UErrorCode status = U_ZERO_ERROR;
|
||||
UResourceBundle* bundle = NULL;
|
||||
char* icuid = NULL;
|
||||
UChar apiStd[MAX_LENGTH_ID];
|
||||
char apiStdName[MAX_LENGTH_ID];
|
||||
char regStdName[MAX_LENGTH_ID];
|
||||
char tmpid[MAX_LENGTH_ID];
|
||||
int32_t apiStdLength = 0;
|
||||
int32_t len;
|
||||
int id;
|
||||
int errorCode;
|
||||
char ISOcode[3]; /* 2 letter iso code */
|
||||
|
||||
LONG result;
|
||||
TZI tziKey;
|
||||
|
@ -246,13 +279,23 @@ uprv_detectWindowsTimeZone() {
|
|||
uprv_memcpy((char *)&tziKey.daylightDate, (char*)&apiTZI.DaylightDate,
|
||||
sizeof(apiTZI.DaylightDate));
|
||||
|
||||
/* Convert the wchar_t* standard name to char* */
|
||||
uprv_memset(apiStdName, 0, sizeof(apiStdName));
|
||||
u_strFromWCS(apiStd, MAX_LENGTH_ID, &apiStdLength, apiTZI.StandardName, -1, &status);
|
||||
u_austrncpy(apiStdName, apiStd, apiStdLength);
|
||||
|
||||
tmpid[0] = 0;
|
||||
|
||||
id = GetUserGeoID(GEOCLASS_NATION);
|
||||
errorCode = GetGeoInfo(id,GEO_ISO2,ISOcode,3,0);
|
||||
|
||||
bundle = ures_openDirect(NULL, "windowsZones", &status);
|
||||
ures_getByKey(bundle, "mapTimezones", bundle, &status);
|
||||
|
||||
/* Note: We get the winid not from static tables but from resource bundle. */
|
||||
while (U_SUCCESS(status) && ures_hasNext(bundle)) {
|
||||
UBool idFound = FALSE;
|
||||
const char* winid;
|
||||
int32_t len;
|
||||
UResourceBundle* winTZ = ures_getNextResource(bundle, NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
break;
|
||||
|
@ -268,22 +311,62 @@ uprv_detectWindowsTimeZone() {
|
|||
tziKey.daylightBias = tziReg.daylightBias;
|
||||
|
||||
if (uprv_memcmp((char *)&tziKey, (char*)&tziReg, sizeof(tziKey)) == 0) {
|
||||
const UChar* icuTZ = ures_getStringByKey(winTZ, "001", &len, &status);
|
||||
const UChar* icuTZ = NULL;
|
||||
if (errorCode != 0) {
|
||||
icuTZ = ures_getStringByKey(winTZ, ISOcode, &len, &status);
|
||||
}
|
||||
if (errorCode==0 || icuTZ==NULL) {
|
||||
/* fallback to default "001" and reset status */
|
||||
status = U_ZERO_ERROR;
|
||||
icuTZ = ures_getStringByKey(winTZ, "001", &len, &status);
|
||||
}
|
||||
|
||||
if (U_SUCCESS(status)) {
|
||||
icuid = (char*)uprv_malloc(sizeof(char) * (len + 1));
|
||||
uprv_memset(icuid, 0, len + 1);
|
||||
u_austrncpy(icuid, icuTZ, len);
|
||||
/* Get the standard name from the registry key to compare with
|
||||
the one from Windows API call. */
|
||||
uprv_memset(regStdName, 0, sizeof(regStdName));
|
||||
result = getSTDName(winid, regStdName, sizeof(regStdName));
|
||||
if (result == ERROR_SUCCESS) {
|
||||
if (uprv_strcmp(apiStdName, regStdName) == 0) {
|
||||
idFound = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* tmpid buffer holds the ICU timezone ID corresponding to the timezone ID from Windows.
|
||||
* If none is found, tmpid buffer will contain a fallback ID (i.e. the time zone ID matching
|
||||
* the current time zone information)
|
||||
*/
|
||||
if (idFound || tmpid[0] == 0) {
|
||||
/* if icuTZ has more than one city, take only the first (i.e. terminate icuTZ at first space) */
|
||||
int index=0;
|
||||
while (! (*icuTZ == '\0' || *icuTZ ==' ')) {
|
||||
tmpid[index++]=(char)(*icuTZ++); /* safe to assume 'char' is ASCII compatible on windows */
|
||||
}
|
||||
tmpid[index]='\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ures_close(winTZ);
|
||||
if (icuid != NULL) {
|
||||
if (idFound) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ures_close(bundle);
|
||||
/*
|
||||
* Copy the timezone ID to icuid to be returned.
|
||||
*/
|
||||
if (tmpid[0] != 0) {
|
||||
len = uprv_strlen(tmpid);
|
||||
icuid = (char*)uprv_malloc(sizeof(char) * (len + 1));
|
||||
uprv_memset(icuid, 0, len + 1);
|
||||
if (icuid != NULL) {
|
||||
uprv_strcpy(icuid, tmpid);
|
||||
}
|
||||
}
|
||||
|
||||
ures_close(bundle);
|
||||
|
||||
return icuid;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue