module TimezoneParser::Windows
Windows
module
Constants
- LCIDToLocaleName
function int
LCIDToLocaleName
( In LCID Locale, Out_opt LPWSTR lpName, In int cchName, In DWORD dwFlags ); @see msdn.microsoft.com/en-us/library/windows/desktop/dd318698.aspx- LOCALE_NAME_MAX_LENGTH
Max locale length
- TimeZonePath
Windows
Registry path to Time Zone data
Public Class Methods
collectMUIOffsets(metazoneList, locales)
click to toggle source
# File lib/timezone_parser/data/windows.rb, line 119 def self.collectMUIOffsets(metazoneList, locales) enUS = locales.key('en-US') baseMetazone = metazoneList[enUS] types = ['display', 'daylight', 'standard'] type_bases = [0, 0, 0, 3, 3, 3, nil, 7, 7, 7] offsets = {} baseMetazone.each do |id, name| data = {} type = id % 10 type_base = type_bases[type] data['Type'] = types[type - type_base] data['Name'] = baseMetazone[(id / 10) * 10 + type_base + types.index('standard')] offsets[id] = data unless data['Name'].nil? end Hash[offsets.to_a.sort_by { |o| o.first }] end
correctMUIOffsetNames(offsets, metazoneList, locales)
click to toggle source
# File lib/timezone_parser/data/windows.rb, line 136 def self.correctMUIOffsetNames(offsets, metazoneList, locales) enUS = locales.key('en-US') baseMetazone = metazoneList[enUS] offsets.each do |id, data| actualMetazone = nil baseMetazone.each do |zoneid, name| if id != zoneid and name == data['Name'] actualMetazone = offsets[zoneid]['Name'] break end end data['Name'] = actualMetazone if actualMetazone end offsets end
errors()
click to toggle source
# File lib/timezone_parser/data/windows.rb, line 18 def self.errors @@Errors end
getLocales(lcids)
click to toggle source
# File lib/timezone_parser/data/windows.rb, line 104 def self.getLocales(lcids) locales = {} lcids.each do |lcid| localeMem = Fiddle::Pointer.malloc(LOCALE_NAME_MAX_LENGTH) chars = LCIDToLocaleName.call(lcid, localeMem, LOCALE_NAME_MAX_LENGTH, 0) if chars.zero? puts "Warning: Failed to translate LCID (#{lcid}) to locale name!" next end locale = localeMem.to_s((chars-1)*2).force_encoding(Encoding::UTF_16LE).encode(Encoding::UTF_8) locales[lcid] = locale end locales end
getMUIOffsets(path = TimeZonePath)
click to toggle source
# File lib/timezone_parser/data/windows.rb, line 77 def self.getMUIOffsets(path = TimeZonePath) offsets = {} begin Win32::Registry::HKEY_LOCAL_MACHINE.open(path, Win32::Registry::KEY_READ).each_key do |key, wtime| Win32::Registry::HKEY_LOCAL_MACHINE.open(path + '\\' + key, Win32::Registry::KEY_READ) do |reg| muiDisplay = reg.read_s('MUI_Display') muiDlt = reg.read_s('MUI_Dlt') muiStd = reg.read_s('MUI_Std') offsets[self.parseMUI(muiDisplay)] = { 'Type' => 'display', 'Name' => key } offsets[self.parseMUI(muiDlt)] = { 'Type' => 'daylight', 'Name' => key } offsets[self.parseMUI(muiStd)] = { 'Type' => 'standard', 'Name' => key } end end rescue Win32::Registry::Error => e @@Errors << e.message end puts @@Errors unless @@Errors.empty? Hash[offsets.to_a.sort_by { |o| o.first }] end
getTimezones(path = TimeZonePath)
click to toggle source
# File lib/timezone_parser/data/windows.rb, line 34 def self.getTimezones(path = TimeZonePath) timezones = {} timezones['North Pacific Standard Time'] = { 'standard' => 3600 * -8, 'daylight' => 3600 * -7 } timezones['Russia TZ 5 Standard Time'] = { 'standard' => 3600 * 6, 'daylight' => 3600 * 6 } begin Win32::Registry::HKEY_LOCAL_MACHINE.open(path, Win32::Registry::KEY_READ).each_key do |key, wtime| Win32::Registry::HKEY_LOCAL_MACHINE.open(path + '\\' + key, Win32::Registry::KEY_READ) do |reg| timezones[key] ||= {} tzi = reg.read('TZI', Win32::Registry::REG_BINARY).last # TZI Structure (http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481.aspx) # typedef struct _REG_TZI_FORMAT # { # LONG Bias; # LONG StandardBias; # LONG DaylightBias; # SYSTEMTIME StandardDate; # SYSTEMTIME DaylightDate; # } REG_TZI_FORMAT; unpacked = tzi.unpack('lllSSSSSSSSSSSSSSSS') timezones[key]['standard'] = (0 - unpacked[0] - unpacked[1]) * 60 timezones[key]['daylight'] = (0 - unpacked[0] - unpacked[2]) * 60 end end rescue Win32::Registry::Error => e @@Errors << e.message end timezones = Hash[timezones.to_a.sort_by { |d| d.first } ] timezones end
getTimezonesUTC()
click to toggle source
# File lib/timezone_parser/data/windows.rb, line 67 def self.getTimezonesUTC() timezones = {} ((1..13).to_a + (-12..-1).to_a.reverse).each do |o| name = "UTC%+03d" % o timezones[name] = { 'standard' => 3600 * o } timezones[name]['daylight'] = timezones[name]['standard'] end timezones end
getVersion(path = TimeZonePath)
click to toggle source
# File lib/timezone_parser/data/windows.rb, line 22 def self.getVersion(path = TimeZonePath) return @@Version if @@Version begin Win32::Registry::HKEY_LOCAL_MACHINE.open(path, Win32::Registry::KEY_READ) do |reg| @@Version = reg['TzVersion', Win32::Registry::REG_DWORD].to_s(16) end rescue Win32::Registry::Error => e @@Errors << e.message end @@Version end
parseMUI(str)
click to toggle source
# File lib/timezone_parser/data/windows.rb, line 98 def self.parseMUI(str) parts = str.split(',') puts "Warning: Unexpected dll name #{parts.first}" if parts.first != '@tzres.dll' parts.last.to_i.abs end
parseMetazones(metazoneList, offsets, locales)
click to toggle source
# File lib/timezone_parser/data/windows.rb, line 152 def self.parseMetazones(metazoneList, offsets, locales) metazones = {} metazoneList.each do |lcid, data| locale = locales[lcid] if locale.nil? puts "Warning: No translation to locale name from LCID (#{lcid}), skipping!" next end metazones[locale] = InsensitiveHash.new offsets.each do |id, info| unless data.has_key?(id) puts "Warning: Didn't found timezone name for #{id} for #{locale} locale, skipping!" next end name = data[id] metazones[locale][name] ||= {} metazones[locale][name]['Types'] ||= [] metazones[locale][name]['Metazones'] ||= [] types = [] types << info['Type'] if info.has_key?('Type') if info['Type'] == 'display' types = ['daylight', 'standard'] end metazones[locale][name]['Types'] += types metazones[locale][name]['Metazones'] << info['Name'] metazones[locale][name]['Types'].uniq! metazones[locale][name]['Metazones'].uniq! end metazones[locale] = Hash[metazones[locale].to_a.sort_by { |d| d.first } ] end metazones = Hash[metazones.to_a.sort_by { |d| d.first } ] metazones end