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.
- checksums.yaml +4 -4
- data/Rakefile +56 -21
- data/data/version.yml +4 -4
- data/data/windows_locales.yaml +66 -0
- data/data/windows_tzres.yaml +1600 -0
- data/lib/timezone_parser/data/cldr.rb +2 -2
- data/lib/timezone_parser/data/tzinfo.rb +1 -7
- data/lib/timezone_parser/data/windows.rb +57 -11
- data/lib/timezone_parser/version.rb +1 -1
- data/spec/abbreviation_spec.rb +10 -10
- data/spec/rails_zone_spec.rb +1 -1
- data/spec/timezone_spec.rb +7 -7
- data/spec/windows_zone_spec.rb +1 -1
- metadata +5 -4
|
@@ -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]
|
|
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.
|
|
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(
|
|
70
|
-
offsets[self.parseMUI(
|
|
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(',')
|
|
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.
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
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
|
-
|
|
98
|
-
|
|
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
|
data/spec/abbreviation_spec.rb
CHANGED
|
@@ -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
|
|
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
|
|
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(['
|
|
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(['
|
|
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?('
|
|
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
|
|
119
|
-
expect(TimezoneParser::Abbreviation::getOffsets('
|
|
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
|
|
125
|
-
expect(TimezoneParser::Abbreviation::getTimezones('
|
|
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
|
|
data/spec/rails_zone_spec.rb
CHANGED
|
@@ -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
|
|
data/spec/timezone_spec.rb
CHANGED
|
@@ -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 "
|
|
30
|
-
expect(TimezoneParser::Timezone.new('
|
|
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/
|
|
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([
|
|
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 "
|
|
97
|
-
expect(TimezoneParser::Timezone::getTimezones('
|
|
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
|
|
data/spec/windows_zone_spec.rb
CHANGED
|
@@ -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/
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|