TimezoneParser 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,8 +32,8 @@ module TimezoneParser
32
32
  return @@Version if @@Version
33
33
  content = File.read(source + 'dtd' + 'ldml.dtd')
34
34
  content.gsub!(/<!--.*?-->/, '')
35
- data = content.match(/\s+cldrVersion\s+[\#\w\s]+\s+"(\d+)"\s*\>/)
36
- @@Version = data[1].to_i if data
35
+ data = content.match(/\s+cldrVersion\s+[\#\w\s]+\s+"([\d\.]+)"\s*\>/)
36
+ @@Version = data[1] if data
37
37
  @@Version
38
38
  end
39
39
 
@@ -49,13 +49,7 @@ module TimezoneParser
49
49
 
50
50
  def self.getVersion(source = TZDataPath)
51
51
  return @@Version if @@Version
52
- File.open(source + 'Makefile', 'r', { :encoding => 'UTF-8:UTF-8' }) do |file|
53
- file.each_line do |line|
54
- line = line.gsub(/#.*$/, '')
55
- v = line.match(/^\s*VERSION\s*=\s*(\w+)\s*$/)
56
- @@Version = v[1] if v
57
- end
58
- end
52
+ @@Version = File.read(source + 'version', { :mode => 'r', :encoding => 'UTF-8:UTF-8' }).strip
59
53
  @@Version
60
54
  end
61
55
 
@@ -63,39 +63,85 @@ module TimezoneParser
63
63
  begin
64
64
  Win32::Registry::HKEY_LOCAL_MACHINE.open(path, Win32::Registry::KEY_READ).each_key do |key, wtime|
65
65
  Win32::Registry::HKEY_LOCAL_MACHINE.open(path + '\\' + key, Win32::Registry::KEY_READ) do |reg|
66
+ muiDisplay = reg.read_s('MUI_Display')
66
67
  muiDlt = reg.read_s('MUI_Dlt')
67
68
  muiStd = reg.read_s('MUI_Std')
68
69
 
69
- offsets[self.parseMUI(muiDlt)] = ['daylight', key]
70
- offsets[self.parseMUI(muiStd)] = ['standard', key]
70
+ offsets[self.parseMUI(muiDisplay)] = { 'Type' => 'display', 'Name' => key }
71
+ offsets[self.parseMUI(muiDlt)] = { 'Type' => 'daylight', 'Name' => key }
72
+ offsets[self.parseMUI(muiStd)] = { 'Type' => 'standard', 'Name' => key }
71
73
  end
72
74
  end
73
75
  rescue Win32::Registry::Error => e
74
76
  @@Errors << e.message
75
77
  end
76
- puts @@Errors
77
- offsets
78
+ puts @@Errors unless @@Errors.empty?
79
+ Hash[offsets.to_a.sort_by { |o| o.first }]
78
80
  end
79
81
 
80
82
  def self.parseMUI(str)
81
- str.split(',').last.to_i.abs
83
+ parts = str.split(',')
84
+ puts "Warning: Unexpected dll name #{parts.first}" if parts.first != '@tzres.dll'
85
+ parts.last.to_i.abs
82
86
  end
83
87
 
84
- def self.parseMetazones(metazoneList, offsets)
85
- metazones = {}
86
- metazoneList.each do |lcid, data|
88
+ def self.getLocales(lcids)
89
+ locales = {}
90
+ lcids.each do |lcid|
87
91
  localeMem = Fiddle::Pointer.malloc(LOCALE_NAME_MAX_LENGTH)
88
92
  chars = LCIDToLocaleName.call(lcid, localeMem, LOCALE_NAME_MAX_LENGTH, 0)
89
- return nil if chars.zero?
93
+ if chars.zero?
94
+ puts "Warning: Failed to translate LCID (#{lcid}) to locale name!"
95
+ next
96
+ end
90
97
  locale = localeMem.to_s((chars-1)*2).force_encoding(Encoding::UTF_16LE).encode(Encoding::UTF_8)
98
+ locales[lcid] = locale
99
+ end
100
+ locales
101
+ end
102
+
103
+ def self.collectMUIOffsets(metazoneList, locales)
104
+ enUS = locales.key('en-US')
105
+ baseMetazone = metazoneList[enUS]
106
+ types = ['display', 'daylight', 'standard']
107
+ type_bases = [0, 0, 0, 3, 3, 3, nil, 7, 7, 7]
108
+ offsets = {}
109
+ baseMetazone.each do |id, name|
110
+ data = {}
111
+ type = id % 10
112
+ type_base = type_bases[type]
113
+ data['Type'] = types[type - type_base]
114
+ data['Name'] = baseMetazone[(id / 10) * 10 + type_base + types.index('standard')]
115
+ offsets[id] = data unless data['Name'].nil?
116
+ end
117
+ offsets
118
+ end
119
+
120
+ def self.parseMetazones(metazoneList, offsets, locales)
121
+ metazones = {}
122
+ metazoneList.each do |lcid, data|
123
+ locale = locales[lcid]
124
+ if locale.nil?
125
+ puts "Warning: No translation to locale name from LCID (#{lcid}), skipping!"
126
+ next
127
+ end
91
128
  metazones[locale] = {}
92
129
  offsets.each do |id, info|
130
+ unless data.has_key?(id)
131
+ puts "Warning: Didn't found timezone name for #{id} for #{locale} locale, skipping!"
132
+ next
133
+ end
93
134
  name = data[id]
94
135
  metazones[locale][name] ||= {}
95
136
  metazones[locale][name]['Types'] ||= []
96
137
  metazones[locale][name]['Metazones'] ||= []
97
- metazones[locale][name]['Types'] << info.first
98
- metazones[locale][name]['Metazones'] << info.last
138
+ types = []
139
+ types << info['Type'] if info.has_key?('Type')
140
+ if info['Type'] == 'display'
141
+ types = ['daylight', 'standard']
142
+ end
143
+ metazones[locale][name]['Types'] += types
144
+ metazones[locale][name]['Metazones'] << info['Name']
99
145
  metazones[locale][name]['Types'].uniq!
100
146
  metazones[locale][name]['Metazones'].uniq!
101
147
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
  module TimezoneParser
3
3
  # Version
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
@@ -35,9 +35,9 @@ describe TimezoneParser do
35
35
  context 'before specified time' do
36
36
  it 'should return correct offsets for ADT' do
37
37
  expect(TimezoneParser::Abbreviation.new('ADT').setTime(DateTime.parse('1982-04-30T21:00:00+00:00')).getOffsets).to eq([-10800])
38
- expect(TimezoneParser::Abbreviation.new('ADT').setTime(DateTime.parse('1982-04-30T21:00:01+00:00')).getOffsets).to eq([-10800, 14400])
39
- expect(TimezoneParser::Abbreviation.new('ADT').setTime(DateTime.parse('1982-09-30T19:59:59+00:00')).getOffsets).to eq([-10800, 14400])
40
- expect(TimezoneParser::Abbreviation.new('ADT').setTime(DateTime.parse('1982-09-30T20:00:00+00:00')).getOffsets).to eq([-10800, 14400])
38
+ expect(TimezoneParser::Abbreviation.new('ADT').setTime(DateTime.parse('1982-04-30T21:00:01+00:00')).getOffsets).to eq([-10800])
39
+ expect(TimezoneParser::Abbreviation.new('ADT').setTime(DateTime.parse('1982-09-30T19:59:59+00:00')).getOffsets).to eq([-10800])
40
+ expect(TimezoneParser::Abbreviation.new('ADT').setTime(DateTime.parse('1982-09-30T20:00:00+00:00')).getOffsets).to eq([-10800])
41
41
  expect(TimezoneParser::Abbreviation.new('ADT').setTime(DateTime.parse('1983-03-30T21:00:00+00:00'), DateTime.parse('1982-09-30T20:00:00+00:00')).getOffsets).to eq([-10800])
42
42
  end
43
43
  end
@@ -56,9 +56,9 @@ describe TimezoneParser do
56
56
  context 'in specified region' do
57
57
  it 'should return correct offsets for ADT' do
58
58
  expect(TimezoneParser::Abbreviation.new('ADT').set([]).getOffsets).to eq([-10800])
59
- expect(TimezoneParser::Abbreviation.new('ADT').set(['IQ']).getOffsets).to eq([14400])
59
+ expect(TimezoneParser::Abbreviation.new('ADT').set(['BM']).getOffsets).to eq([-10800])
60
60
  expect(TimezoneParser::Abbreviation.new('ADT').set(['GL']).getOffsets).to eq([-10800])
61
- expect(TimezoneParser::Abbreviation.new('ADT').setTime(DateTime.parse('2007-10-01T00:00:00+00:00')).set(['IQ', 'CA']).getOffsets).to eq([-10800, 14400])
61
+ expect(TimezoneParser::Abbreviation.new('ADT').setTime(DateTime.parse('2007-10-01T00:00:00+00:00')).set(['BM', 'CA']).getOffsets).to eq([-10800])
62
62
  end
63
63
  end
64
64
 
@@ -96,7 +96,7 @@ describe TimezoneParser do
96
96
 
97
97
  describe '.isValid?' do
98
98
  it 'should be valid abbreviation' do
99
- expect(TimezoneParser::Abbreviation::isValid?('WGT')).to be true
99
+ expect(TimezoneParser::Abbreviation::isValid?('WAST')).to be true
100
100
  end
101
101
  end
102
102
 
@@ -115,14 +115,14 @@ describe TimezoneParser do
115
115
  end
116
116
 
117
117
  describe '.getOffsets' do
118
- it 'should return offsets for WGT abbreviation in GL region' do
119
- expect(TimezoneParser::Abbreviation::getOffsets('WGT', DateTime.now, nil, ['GL'])).to eq([-10800])
118
+ it 'should return offsets for WAST abbreviation in NA region' do
119
+ expect(TimezoneParser::Abbreviation::getOffsets('WAST', DateTime.now, nil, ['NA'])).to eq([7200])
120
120
  end
121
121
  end
122
122
 
123
123
  describe '.getTimezones' do
124
- it 'should return timezones for WGT abbreviation' do
125
- expect(TimezoneParser::Abbreviation::getTimezones('WGT', DateTime.parse('1916-07-28T03:26:56+00:00'), DateTime.parse('1916-07-28T01:14:40+00:00'), ['GL'])).to eq(['America/Danmarkshavn'])
124
+ it 'should return timezones for WAST abbreviation' do
125
+ expect(TimezoneParser::Abbreviation::getTimezones('WAST', DateTime.parse('1988-07-28T03:26:56+00:00'), DateTime.parse('1994-07-28T01:14:40+00:00'), ['NA'])).to eq(['Africa/Windhoek'])
126
126
  end
127
127
  end
128
128
 
@@ -58,7 +58,7 @@ describe TimezoneParser do
58
58
 
59
59
  describe '.getOffsets' do
60
60
  it 'should return all offsets for "Nuku\'alofa"' do
61
- expect(TimezoneParser::RailsZone::getOffsets('Nuku\'alofa', DateTime.now, nil, ['en', 'ru'], true)).to eq([46800])
61
+ expect(TimezoneParser::RailsZone::getOffsets('Nuku\'alofa', DateTime.now, nil, ['en', 'ru'], true)).to eq([46800, 50400])
62
62
  end
63
63
  end
64
64
 
@@ -20,14 +20,14 @@ describe TimezoneParser do
20
20
 
21
21
  it 'should be valid case-insensitive' do
22
22
  expect(TimezoneParser::Timezone.new('büsingen').isValid?).to be true
23
- pending('TODO: Unicode case insensitivity')
24
23
  expect(TimezoneParser::Timezone.new('bÜsingen').isValid?).to be true
24
+ expect(TimezoneParser::Timezone.new('bÜsinGEN').isValid?).to be true
25
25
  end
26
26
  end
27
27
 
28
28
  describe '#getOffsets' do
29
- it 'should return all offsets for "Պարսկաստանի ամառային ժամանակ"' do
30
- expect(TimezoneParser::Timezone.new('Պարսկաստանի ամառային ժամանակ').getOffsets).to eq([16200])
29
+ it 'should return all offsets for "Ալյասկայի ամառային ժամանակ"' do
30
+ expect(TimezoneParser::Timezone.new('Ալյասկայի ամառային ժամանակ').getOffsets).to eq([-28800])
31
31
  end
32
32
  end
33
33
 
@@ -62,8 +62,8 @@ describe TimezoneParser do
62
62
 
63
63
  context 'timezones from specified time range' do
64
64
  it 'should find timezones between specified time range' do
65
- expect(TimezoneParser::Timezone.new('Maskvos laikas').setTime(DateTime.parse('1991-03-30T23:00:00+00:00'), DateTime.parse('1990-06-30T23:00:00+00:00')).getTimezones).to eq(['Europe/Kaliningrad', 'Europe/Minsk', 'Europe/Moscow', 'Europe/Samara', 'Europe/Vilnius', 'Europe/Zaporozhye'])
66
- expect(TimezoneParser::Timezone.new('Maskvos laikas').setTime(DateTime.parse('2010-03-27T22:00:00+00:00'), DateTime.parse('1997-03-30T01:00:00+00:00')).getTimezones).to eq(['Europe/Moscow', 'Europe/Volgograd'])
65
+ expect(TimezoneParser::Timezone.new('Maskvos laikas').setTime(DateTime.parse('1991-03-30T23:00:00+00:00'), DateTime.parse('1990-06-30T23:00:00+00:00')).getTimezones).to eq(['Europe/Minsk', 'Europe/Moscow', 'Europe/Samara', 'Europe/Zaporozhye'])
66
+ expect(TimezoneParser::Timezone.new('Maskvos laikas').setTime(DateTime.parse('2010-03-27T22:00:00+00:00'), DateTime.parse('1997-03-30T01:00:00+00:00')).getTimezones).to eq(["Europe/Astrakhan", "Europe/Moscow", "Europe/Saratov", "Europe/Ulyanovsk", "Europe/Volgograd"])
67
67
  end
68
68
  end
69
69
  end
@@ -93,8 +93,8 @@ describe TimezoneParser do
93
93
  end
94
94
 
95
95
  describe '.getTimezones' do
96
- it 'should return all timezones for "Grinwish gaƒoƒome"' do
97
- expect(TimezoneParser::Timezone::getTimezones('Grinwish gaƒoƒome', nil, nil, ['dz', 'ee'], ['IM'])).to eq(['Europe/London'])
96
+ it 'should return all timezones for "Britain dzomeŋɔli gaƒoƒome"' do
97
+ expect(TimezoneParser::Timezone::getTimezones('Britain dzomeŋɔli gaƒoƒome', nil, nil, ['dz', 'ee'], ['IM'])).to eq(['Europe/London'])
98
98
  end
99
99
  end
100
100
 
@@ -28,7 +28,7 @@ describe TimezoneParser do
28
28
 
29
29
  describe '#getTimezones' do
30
30
  it 'should return all timezones for "كوريا - التوقيت الرسمي"' do
31
- expect(TimezoneParser::WindowsZone.new('كوريا - التوقيت الرسمي').getTimezones).to eq(['Asia/Pyongyang', 'Asia/Seoul'])
31
+ expect(TimezoneParser::WindowsZone.new('كوريا - التوقيت الرسمي').getTimezones).to eq(['Asia/Seoul'])
32
32
  end
33
33
 
34
34
  it 'it should not find "GMT Daylight Time" in "en-GB" locale' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: TimezoneParser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dāvis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-29 00:00:00.000000000 Z
11
+ date: 2017-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzinfo
@@ -187,8 +187,10 @@ files:
187
187
  - data/rails_i18n.dat
188
188
  - data/timezones.dat
189
189
  - data/version.yml
190
+ - data/windows_locales.yaml
190
191
  - data/windows_offsets.dat
191
192
  - data/windows_timezones.dat
193
+ - data/windows_tzres.yaml
192
194
  - data/windows_zonenames.dat
193
195
  - lib/timezone_parser.rb
194
196
  - lib/timezone_parser/abbreviation.rb
@@ -228,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
228
230
  version: '0'
229
231
  requirements: []
230
232
  rubyforge_project:
231
- rubygems_version: 2.4.1
233
+ rubygems_version: 2.6.12
232
234
  signing_key:
233
235
  specification_version: 4
234
236
  summary: Parse Timezone names written in any language to offsets and TimeZone identifiers
@@ -239,4 +241,3 @@ test_files:
239
241
  - spec/timezone_parser_spec.rb
240
242
  - spec/timezone_spec.rb
241
243
  - spec/windows_zone_spec.rb
242
- has_rdoc: