Index: src/timezone/pgtz.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/timezone/pgtz.c,v retrieving revision 1.24 diff -c -r1.24 pgtz.c *** src/timezone/pgtz.c 30 Aug 2004 02:54:42 -0000 1.24 --- src/timezone/pgtz.c 31 Aug 2004 19:30:08 -0000 *************** *** 822,829 **** --- 822,832 ---- { int i; char tzname[128]; + char localtzname[128]; time_t t = time(NULL); struct tm *tm = localtime(&t); + HKEY rootKey; + int idx; if (!tm) { *************** *** 846,851 **** --- 849,958 ---- } } + /* + * Localized Windows versions return localized names for the + * timezones. Scan the registry to find the english name, + * and then try matching against the table again. + */ + ZeroMemory(localtzname, sizeof(localtzname)); + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones", + 0, + KEY_READ, + &rootKey) != ERROR_SUCCESS) + { + ereport(WARNING, + (errmsg_internal("could not open registry key to identify Windows timezone \"%s\": %i", tzname, (int)GetLastError()))); + return NULL; + } + + for (idx = 0; ; idx++) + { + char keyname[256]; + char zonename[256]; + DWORD namesize = sizeof(keyname); + FILETIME lastwrite; + HKEY key; + LONG r; + + ZeroMemory(keyname,sizeof(keyname)); + + if ((r=RegEnumKeyEx(rootKey, + idx, + keyname, + &namesize, + NULL, + NULL, + NULL, + &lastwrite)) != ERROR_SUCCESS) + { + if (r == ERROR_NO_MORE_ITEMS) + break; + ereport(WARNING, + (errmsg_internal("could not enumerate registry subkeys to identify Windows timezone \"%s\": %i", tzname, (int)r))); + break; + } + + if ((r=RegOpenKeyEx(rootKey,keyname,0,KEY_READ,&key)) != ERROR_SUCCESS) + { + ereport(WARNING, + (errmsg_internal("could not open registry subkey to identify Windows timezone \"%s\": %i", tzname, (int)r))); + break; + } + + ZeroMemory(zonename,sizeof(zonename)); + namesize = sizeof(zonename); + if ((r=RegQueryValueEx(key, "Std", NULL, NULL, zonename, &namesize)) != ERROR_SUCCESS) + { + ereport(WARNING, + (errmsg_internal("could not query value for 'std' to identify Windows timezone \"%s\": %i", tzname, (int)r))); + RegCloseKey(key); + break; + } + if (!strcmp(tzname, zonename)) + { + /* Matched zone */ + strcpy(localtzname, keyname); + RegCloseKey(key); + break; + } + ZeroMemory(zonename, sizeof(zonename)); + namesize = sizeof(zonename); + if ((r=RegQueryValueEx(key, "Dlt", NULL, NULL, zonename, &namesize)) != ERROR_SUCCESS) + { + ereport(WARNING, + (errmsg_internal("could not query value for 'dlt' to identify Windows timezone \"%s\": %i", tzname, (int)r))); + RegCloseKey(key); + break; + } + if (!strcmp(tzname, zonename)) + { + /* Matched DST zone */ + strcpy(localtzname, keyname); + RegCloseKey(key); + break; + } + + RegCloseKey(key); + } + + RegCloseKey(rootKey); + + if (localtzname[0]) + { + /* Found a localized name, so scan for that one too */ + for (i = 0; win32_tzmap[i].stdname != NULL; i++) + { + if (strcmp(localtzname, win32_tzmap[i].stdname) == 0 || + strcmp(localtzname, win32_tzmap[i].dstname) == 0) + { + elog(DEBUG4, "TZ \"%s\" matches localized Windows timezone \"%s\" (\"%s\")", + win32_tzmap[i].pgtzname, tzname, localtzname); + return win32_tzmap[i].pgtzname; + } + } + } + ereport(WARNING, (errmsg("could not find a match for Windows timezone \"%s\"", tzname)));