6
6
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
7
7
*
8
8
* IDENTIFICATION
9
- * $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.24 2004/08/30 02:54:42 momjian Exp $
9
+ * $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.25 2004/09/01 16:21:50 tgl Exp $
10
10
*
11
11
*-------------------------------------------------------------------------
12
12
*/
@@ -822,8 +822,11 @@ identify_system_timezone(void)
822
822
{
823
823
int i ;
824
824
char tzname [128 ];
825
+ char localtzname [256 ];
825
826
time_t t = time (NULL );
826
827
struct tm * tm = localtime (& t );
828
+ HKEY rootKey ;
829
+ int idx ;
827
830
828
831
if (!tm )
829
832
{
@@ -846,6 +849,110 @@ identify_system_timezone(void)
846
849
}
847
850
}
848
851
852
+ /*
853
+ * Localized Windows versions return localized names for the
854
+ * timezone. Scan the registry to find the English name,
855
+ * and then try matching against our table again.
856
+ */
857
+ memset (localtzname , 0 , sizeof (localtzname ));
858
+ if (RegOpenKeyEx (HKEY_LOCAL_MACHINE ,
859
+ "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones" ,
860
+ 0 ,
861
+ KEY_READ ,
862
+ & rootKey ) != ERROR_SUCCESS )
863
+ {
864
+ ereport (WARNING ,
865
+ (errmsg_internal ("could not open registry key to identify Windows timezone: %i" , (int )GetLastError ())));
866
+ return NULL ;
867
+ }
868
+
869
+ for (idx = 0 ; ; idx ++ )
870
+ {
871
+ char keyname [256 ];
872
+ char zonename [256 ];
873
+ DWORD namesize ;
874
+ FILETIME lastwrite ;
875
+ HKEY key ;
876
+ LONG r ;
877
+
878
+ memset (keyname , 0 , sizeof (keyname ));
879
+ namesize = sizeof (keyname );
880
+ if ((r = RegEnumKeyEx (rootKey ,
881
+ idx ,
882
+ keyname ,
883
+ & namesize ,
884
+ NULL ,
885
+ NULL ,
886
+ NULL ,
887
+ & lastwrite )) != ERROR_SUCCESS )
888
+ {
889
+ if (r == ERROR_NO_MORE_ITEMS )
890
+ break ;
891
+ ereport (WARNING ,
892
+ (errmsg_internal ("could not enumerate registry subkeys to identify Windows timezone: %i" , (int )r )));
893
+ break ;
894
+ }
895
+
896
+ if ((r = RegOpenKeyEx (rootKey ,keyname ,0 ,KEY_READ ,& key )) != ERROR_SUCCESS )
897
+ {
898
+ ereport (WARNING ,
899
+ (errmsg_internal ("could not open registry subkey to identify Windows timezone: %i" , (int )r )));
900
+ break ;
901
+ }
902
+
903
+ memset (zonename , 0 , sizeof (zonename ));
904
+ namesize = sizeof (zonename );
905
+ if ((r = RegQueryValueEx (key , "Std" , NULL , NULL , zonename , & namesize )) != ERROR_SUCCESS )
906
+ {
907
+ ereport (WARNING ,
908
+ (errmsg_internal ("could not query value for 'std' to identify Windows timezone: %i" , (int )r )));
909
+ RegCloseKey (key );
910
+ break ;
911
+ }
912
+ if (strcmp (tzname , zonename ) == 0 )
913
+ {
914
+ /* Matched zone */
915
+ strcpy (localtzname , keyname );
916
+ RegCloseKey (key );
917
+ break ;
918
+ }
919
+ memset (zonename , 0 , sizeof (zonename ));
920
+ namesize = sizeof (zonename );
921
+ if ((r = RegQueryValueEx (key , "Dlt" , NULL , NULL , zonename , & namesize )) != ERROR_SUCCESS )
922
+ {
923
+ ereport (WARNING ,
924
+ (errmsg_internal ("could not query value for 'dlt' to identify Windows timezone: %i" , (int )r )));
925
+ RegCloseKey (key );
926
+ break ;
927
+ }
928
+ if (strcmp (tzname , zonename ) == 0 )
929
+ {
930
+ /* Matched DST zone */
931
+ strcpy (localtzname , keyname );
932
+ RegCloseKey (key );
933
+ break ;
934
+ }
935
+
936
+ RegCloseKey (key );
937
+ }
938
+
939
+ RegCloseKey (rootKey );
940
+
941
+ if (localtzname [0 ])
942
+ {
943
+ /* Found a localized name, so scan for that one too */
944
+ for (i = 0 ; win32_tzmap [i ].stdname != NULL ; i ++ )
945
+ {
946
+ if (strcmp (localtzname , win32_tzmap [i ].stdname ) == 0 ||
947
+ strcmp (localtzname , win32_tzmap [i ].dstname ) == 0 )
948
+ {
949
+ elog (DEBUG4 , "TZ \"%s\" matches localized Windows timezone \"%s\" (\"%s\")" ,
950
+ win32_tzmap [i ].pgtzname , tzname , localtzname );
951
+ return win32_tzmap [i ].pgtzname ;
952
+ }
953
+ }
954
+ }
955
+
849
956
ereport (WARNING ,
850
957
(errmsg ("could not find a match for Windows timezone \"%s\"" ,
851
958
tzname )));
0 commit comments