_win32.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. try:
  2. import _winreg as winreg
  3. except ImportError:
  4. try:
  5. import winreg
  6. except ImportError:
  7. winreg = None
  8. from babel.core import get_global
  9. import pytz
  10. # When building the cldr data on windows this module gets imported.
  11. # Because at that point there is no global.dat yet this call will
  12. # fail. We want to catch it down in that case then and just assume
  13. # the mapping was empty.
  14. try:
  15. tz_names = get_global('windows_zone_mapping')
  16. except RuntimeError:
  17. tz_names = {}
  18. def valuestodict(key):
  19. """Convert a registry key's values to a dictionary."""
  20. dict = {}
  21. size = winreg.QueryInfoKey(key)[1]
  22. for i in range(size):
  23. data = winreg.EnumValue(key, i)
  24. dict[data[0]] = data[1]
  25. return dict
  26. def get_localzone_name():
  27. # Windows is special. It has unique time zone names (in several
  28. # meanings of the word) available, but unfortunately, they can be
  29. # translated to the language of the operating system, so we need to
  30. # do a backwards lookup, by going through all time zones and see which
  31. # one matches.
  32. handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
  33. TZLOCALKEYNAME = r'SYSTEM\CurrentControlSet\Control\TimeZoneInformation'
  34. localtz = winreg.OpenKey(handle, TZLOCALKEYNAME)
  35. keyvalues = valuestodict(localtz)
  36. localtz.Close()
  37. if 'TimeZoneKeyName' in keyvalues:
  38. # Windows 7 (and Vista?)
  39. # For some reason this returns a string with loads of NUL bytes at
  40. # least on some systems. I don't know if this is a bug somewhere, I
  41. # just work around it.
  42. tzkeyname = keyvalues['TimeZoneKeyName'].split('\x00', 1)[0]
  43. else:
  44. # Windows 2000 or XP
  45. # This is the localized name:
  46. tzwin = keyvalues['StandardName']
  47. # Open the list of timezones to look up the real name:
  48. TZKEYNAME = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones'
  49. tzkey = winreg.OpenKey(handle, TZKEYNAME)
  50. # Now, match this value to Time Zone information
  51. tzkeyname = None
  52. for i in range(winreg.QueryInfoKey(tzkey)[0]):
  53. subkey = winreg.EnumKey(tzkey, i)
  54. sub = winreg.OpenKey(tzkey, subkey)
  55. data = valuestodict(sub)
  56. sub.Close()
  57. if data.get('Std', None) == tzwin:
  58. tzkeyname = subkey
  59. break
  60. tzkey.Close()
  61. handle.Close()
  62. if tzkeyname is None:
  63. raise LookupError('Can not find Windows timezone configuration')
  64. timezone = tz_names.get(tzkeyname)
  65. if timezone is None:
  66. # Nope, that didn't work. Try adding 'Standard Time',
  67. # it seems to work a lot of times:
  68. timezone = tz_names.get(tzkeyname + ' Standard Time')
  69. # Return what we have.
  70. if timezone is None:
  71. raise pytz.UnknownTimeZoneError('Can not find timezone ' + tzkeyname)
  72. return timezone
  73. def _get_localzone():
  74. if winreg is None:
  75. raise pytz.UnknownTimeZoneError(
  76. 'Runtime support not available')
  77. return pytz.timezone(get_localzone_name())