TimezoneParser 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/README.md +0 -1
- data/Rakefile +4 -6
- data/TimezoneParser.gemspec +2 -5
- data/data/schema.sql +164 -0
- data/lib/timezone_parser.rb +6 -17
- data/lib/timezone_parser/abbreviation.rb +112 -41
- data/lib/timezone_parser/data.rb +0 -102
- data/lib/timezone_parser/data/exporter.rb +242 -0
- data/lib/timezone_parser/data/storage.rb +12 -150
- data/lib/timezone_parser/data/tzinfo.rb +8 -0
- data/lib/timezone_parser/rails_zone.rb +101 -90
- data/lib/timezone_parser/timezone.rb +106 -56
- data/lib/timezone_parser/version.rb +1 -1
- data/lib/timezone_parser/windows_zone.rb +98 -68
- data/lib/timezone_parser/zone_info.rb +89 -18
- data/spec/abbreviation_spec.rb +25 -1
- data/spec/rails_zone_spec.rb +7 -3
- data/spec/timezone_parser_spec.rb +0 -6
- data/spec/timezone_spec.rb +15 -0
- data/spec/windows_zone_spec.rb +9 -2
- metadata +18 -10
data/lib/timezone_parser/data.rb
CHANGED
@@ -13,107 +13,5 @@ module TimezoneParser
|
|
13
13
|
DataDir = RootDir + 'data'
|
14
14
|
# Path to Vendor directory
|
15
15
|
VendorDir = RootDir + 'vendor'
|
16
|
-
|
17
|
-
attr_reader :Offsets
|
18
|
-
attr_reader :Timezones
|
19
|
-
attr_reader :Types
|
20
|
-
attr_reader :Metazones
|
21
|
-
def initialize
|
22
|
-
@Offsets = SortedSet.new
|
23
|
-
@Timezones = SortedSet.new
|
24
|
-
@Types = SortedSet.new
|
25
|
-
@Metazones = SortedSet.new
|
26
|
-
end
|
27
|
-
|
28
|
-
def processEntry(entry, toTime, fromTime, regions = [])
|
29
|
-
@Timezones += entry['Timezones'] if entry['Timezones']
|
30
|
-
@Offsets << entry['Offset'] if entry['Offset']
|
31
|
-
@Types += entry['Types'].map(&:to_sym) if entry['Types']
|
32
|
-
if entry.has_key?('Metazones')
|
33
|
-
entry['Metazones'].each do |zone|
|
34
|
-
@Metazones << zone
|
35
|
-
@Timezones += Storage.getTimezones(zone, toTime, fromTime, regions)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
self
|
39
|
-
end
|
40
|
-
|
41
|
-
def findOffsets(toTime, fromTime, regions = nil, types = nil)
|
42
|
-
types = @Types.to_a unless types
|
43
|
-
types = [:daylight, :standard] if types.empty?
|
44
|
-
@Timezones.each do |timezone|
|
45
|
-
if regions and not regions.empty?
|
46
|
-
timezoneRegions = Data::Storage.TimezoneCountries[timezone]
|
47
|
-
next if timezoneRegions and (timezoneRegions & regions).empty?
|
48
|
-
end
|
49
|
-
begin
|
50
|
-
tz = TZInfo::Timezone.get(timezone)
|
51
|
-
rescue TZInfo::InvalidTimezoneIdentifier
|
52
|
-
tz = nil
|
53
|
-
end
|
54
|
-
next unless tz
|
55
|
-
offsets = []
|
56
|
-
self.class.addOffset(offsets, tz.period_for_utc(fromTime).offset, types)
|
57
|
-
tz.transitions_up_to(toTime, fromTime).each do |transition|
|
58
|
-
self.class.addOffset(offsets, transition.offset, types)
|
59
|
-
end
|
60
|
-
@Offsets += offsets
|
61
|
-
end
|
62
|
-
@Offsets
|
63
|
-
end
|
64
|
-
|
65
|
-
# Load data entries which match specified time
|
66
|
-
# @param data [Array<Hash>] array of entries
|
67
|
-
# @param toTime [DateTime] entries before this date, exclusive
|
68
|
-
# @param fromTime [DateTime] entries after/at this date, inclusive
|
69
|
-
# @return [Array<Hash>] resulting array containing filtered entries
|
70
|
-
def self.loadEntries(data, toTime, fromTime, offsets = false)
|
71
|
-
result = []
|
72
|
-
data.each do |entry|
|
73
|
-
result << entry if (entry['From'] && entry['To'] and toTime > entry['From'] and fromTime < entry['To']) or
|
74
|
-
(entry['From'] && !entry['To'] and toTime > entry['From']) or
|
75
|
-
(!entry['From'] && entry['To'] and fromTime < entry['To']) or
|
76
|
-
(!entry['From'] && !entry['To'])
|
77
|
-
end
|
78
|
-
result.each do |entry|
|
79
|
-
return result if not offsets or (offsets and entry['Offset'])
|
80
|
-
end
|
81
|
-
data.each_index do |i|
|
82
|
-
entry = data[i]
|
83
|
-
nextentry = offsets ? getNextEntry(data, i) : data[i+1]
|
84
|
-
result << entry if ( entry['From'] && entry['To'] and toTime > entry['From'] and fromTime < entry['To'] ) or
|
85
|
-
( entry['To'] and ( (nextentry.nil? and fromTime >= entry['To']) or
|
86
|
-
(nextentry and nextentry['From'] and fromTime >= entry['To'] and toTime <= nextentry['From']) or
|
87
|
-
(!entry['From'] and fromTime < entry['To']) ) ) or
|
88
|
-
( entry['From'] and ( (i.zero? and toTime <= entry['From']) or (!entry['To'] and toTime > entry['From']) ) )
|
89
|
-
end
|
90
|
-
result
|
91
|
-
end
|
92
|
-
|
93
|
-
def self.filterData(data, toTime, fromTime, type, regions)
|
94
|
-
entries = []
|
95
|
-
data.each do |entry|
|
96
|
-
next if type and entry['Types'] and not entry['Types'].include?(type)
|
97
|
-
next if not regions.empty? and entry['Countries'] and (entry['Countries'] & regions).empty?
|
98
|
-
entries << entry
|
99
|
-
end
|
100
|
-
loadEntries(entries, toTime, fromTime, true)
|
101
|
-
end
|
102
|
-
|
103
|
-
protected
|
104
|
-
|
105
|
-
def self.getNextEntry(data, i)
|
106
|
-
j = 1
|
107
|
-
begin
|
108
|
-
entry = data[i+j]
|
109
|
-
j += 1
|
110
|
-
end until entry.nil? or (entry and entry['Offset'])
|
111
|
-
entry
|
112
|
-
end
|
113
|
-
|
114
|
-
def self.addOffset(offsets, offset, types)
|
115
|
-
offsets << offset.utc_total_offset if (offset.dst? and types.include?(:daylight)) or (not offset.dst? and types.include?(:standard))
|
116
|
-
end
|
117
|
-
|
118
16
|
end
|
119
17
|
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'sqlite3'
|
3
|
+
require_relative 'tzinfo'
|
4
|
+
require_relative '../zone_info'
|
5
|
+
|
6
|
+
module TimezoneParser
|
7
|
+
class Data
|
8
|
+
# Timezone data Exporter class
|
9
|
+
class Exporter
|
10
|
+
Database = 'timezones.db'
|
11
|
+
|
12
|
+
public
|
13
|
+
|
14
|
+
def initialize(location)
|
15
|
+
path = location + Database
|
16
|
+
File.delete(path) if File.exist?(path)
|
17
|
+
@Database = SQLite3::Database.new(path.to_s)
|
18
|
+
@DataDir = Data::DataDir
|
19
|
+
end
|
20
|
+
|
21
|
+
def exportDatabase
|
22
|
+
configure
|
23
|
+
loadSchema
|
24
|
+
loadLocales
|
25
|
+
loadTerritories
|
26
|
+
loadTimezones
|
27
|
+
loadTimezoneTerritories
|
28
|
+
loadMetazones
|
29
|
+
loadTimezoneNames
|
30
|
+
loadAbbreviations
|
31
|
+
loadRailsTimezones
|
32
|
+
loadRailsI18N
|
33
|
+
loadWindowsZones
|
34
|
+
loadWindowsZoneTimezones
|
35
|
+
loadWindowsZoneNames
|
36
|
+
finalize
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
@Database = nil
|
42
|
+
@LocaleIds = {}
|
43
|
+
@TerritoryIds = {}
|
44
|
+
@TimezoneIds = {}
|
45
|
+
@MetazoneIds = {}
|
46
|
+
@RailsTimezoneIds = {}
|
47
|
+
@WindowsZoneIds = {}
|
48
|
+
|
49
|
+
def configure
|
50
|
+
@Database.application_id = 'TZPR'.unpack('l>').first.to_s
|
51
|
+
@Database.user_version = TimezoneParser::VERSION.split('.').map(&:to_i).pack('CS>C').unpack('l>').first.to_s
|
52
|
+
@Database.foreign_keys = true
|
53
|
+
@Database.journal_mode = 'off'
|
54
|
+
@Database.temp_store = 'memory'
|
55
|
+
@Database.locking_mode = 'exclusive'
|
56
|
+
@Database.synchronous = 'off'
|
57
|
+
end
|
58
|
+
|
59
|
+
def finalize
|
60
|
+
@Database.execute('ANALYZE')
|
61
|
+
@Database.execute('VACUUM')
|
62
|
+
end
|
63
|
+
|
64
|
+
def normalizeLocale(locale)
|
65
|
+
locale = locale.gsub('_', '-')
|
66
|
+
case locale
|
67
|
+
when 'zh-CN'
|
68
|
+
locale = 'zh-Hans-CN'
|
69
|
+
when 'zh-TW'
|
70
|
+
locale = 'zh-Hant-TW'
|
71
|
+
when 'ha-Latn-NG'
|
72
|
+
locale = 'ha-NG'
|
73
|
+
end
|
74
|
+
locale
|
75
|
+
end
|
76
|
+
|
77
|
+
def getLocaleId(locale)
|
78
|
+
@LocaleIds[normalizeLocale(locale)]
|
79
|
+
end
|
80
|
+
|
81
|
+
def loadSchema
|
82
|
+
schema = File.read(@DataDir + 'schema.sql')
|
83
|
+
@Database.execute_batch(schema)
|
84
|
+
end
|
85
|
+
|
86
|
+
def loadLocales
|
87
|
+
@LocaleIds = {}
|
88
|
+
locales = YAML.load_file(@DataDir + 'locales.yaml')
|
89
|
+
locales.each do |locale|
|
90
|
+
locale = normalizeLocale(locale)
|
91
|
+
@Database.execute('INSERT INTO `Locales` (`Name`) VALUES (?)', locale)
|
92
|
+
@LocaleIds[locale] = @Database.last_insert_row_id
|
93
|
+
end
|
94
|
+
locales.each do |locale|
|
95
|
+
locale = normalizeLocale(locale)
|
96
|
+
if locale.include?('-')
|
97
|
+
parent = locale.split('-')[0..-2].join('-')
|
98
|
+
@Database.execute('UPDATE `Locales` SET `Parent` = ? WHERE `ID` = ?', getLocaleId(parent), getLocaleId(locale))
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def loadTerritories
|
104
|
+
@TerritoryIds = {}
|
105
|
+
territories = YAML.load_file(@DataDir + 'territories.yaml')
|
106
|
+
(territories.to_a.flatten + ['ZZ']).sort.uniq.each do |territory|
|
107
|
+
@Database.execute('INSERT INTO `Territories` (`Territory`) VALUES (?)', territory)
|
108
|
+
@TerritoryIds[territory] = @Database.last_insert_row_id
|
109
|
+
end
|
110
|
+
territories.each do |parent, entries|
|
111
|
+
entries.each do |territory|
|
112
|
+
@Database.execute('INSERT INTO `TerritoryContainment` (`Parent`, `Territory`) VALUES (?, ?)', @TerritoryIds[parent], @TerritoryIds[territory])
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def loadTimezones
|
118
|
+
@TimezoneIds = {}
|
119
|
+
TimezoneParser::TZInfo.getTimezones.each do |timezone|
|
120
|
+
@Database.execute('INSERT INTO `Timezones` (`Name`) VALUES (?)', timezone)
|
121
|
+
@TimezoneIds[timezone] = @Database.last_insert_row_id
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def loadTimezoneTerritories
|
126
|
+
YAML.load_file(@DataDir + 'countries.yaml').each do |timezone, countries|
|
127
|
+
countries.each do |country|
|
128
|
+
@Database.execute('INSERT INTO TimezoneTerritories (Timezone, Territory) VALUES (?, ?)', [@TimezoneIds[timezone], @TerritoryIds[country]])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def loadMetazones
|
134
|
+
@MetazoneIds = {}
|
135
|
+
YAML.load_file(@DataDir + 'metazones.yaml').each do |metazone, entries|
|
136
|
+
@Database.execute('INSERT INTO `Metazones` (`Name`) VALUES (?)', [metazone])
|
137
|
+
@MetazoneIds[metazone] = @Database.last_insert_row_id
|
138
|
+
entries.each do |entry|
|
139
|
+
@Database.execute('INSERT INTO `MetazonePeriods` (`Metazone`, `From`, `To`) VALUES (?, ?, ?)', [@MetazoneIds[metazone], entry['From'], entry['To']])
|
140
|
+
period = @Database.last_insert_row_id
|
141
|
+
entry['Timezones'].each do |timezone|
|
142
|
+
@Database.execute('INSERT INTO `MetazonePeriod_Timezones` (`MetazonePeriod`, `Timezone`) VALUES (?, ?)', [period, @TimezoneIds[timezone]])
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def getTypes(data)
|
149
|
+
types = nil
|
150
|
+
if data['Types']
|
151
|
+
types = types.to_i | TimezoneParser::ZoneInfo::TIMEZONE_TYPE_STANDARD if data['Types'].include?('standard')
|
152
|
+
types = types.to_i | TimezoneParser::ZoneInfo::TIMEZONE_TYPE_DAYLIGHT if data['Types'].include?('daylight')
|
153
|
+
end
|
154
|
+
types
|
155
|
+
end
|
156
|
+
|
157
|
+
def loadTimezoneNames
|
158
|
+
YAML.load_file(@DataDir + 'timezones.yaml').each do |locale, localeData|
|
159
|
+
localeData.each do |name, data|
|
160
|
+
@Database.execute('INSERT INTO TimezoneNames (`Locale`, `Name`, `NameLowercase`, Types) VALUES (?, ?, ?, ?)', [getLocaleId(locale), name, name.downcase, getTypes(data)])
|
161
|
+
nameId = @Database.last_insert_row_id
|
162
|
+
data['Timezones'].to_a.each do |timezone|
|
163
|
+
@Database.execute('INSERT INTO TimezoneName_Timezones (`Name`, `Timezone`) VALUES (?, ?)', [nameId, @TimezoneIds[timezone]])
|
164
|
+
end
|
165
|
+
data['Metazones'].to_a.each do |metazone|
|
166
|
+
@Database.execute('INSERT INTO TimezoneName_Metazones (`Name`, `Metazone`) VALUES (?, ?)', [nameId, @MetazoneIds[metazone]])
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def loadAbbreviations
|
173
|
+
YAML.load_file(@DataDir + 'abbreviations.yaml').each do |abbreviation, entries|
|
174
|
+
@Database.execute('INSERT INTO `Abbreviations` (`Name`, `NameLowercase`) VALUES (?, ?)', [abbreviation, abbreviation.downcase])
|
175
|
+
abbreviationId = @Database.last_insert_row_id
|
176
|
+
entries.each do |entry|
|
177
|
+
@Database.execute('INSERT INTO `AbbreviationOffsets` (`Abbreviation`, `Offset`, `Types`, `From`, `To`) VALUES (?, ?, ?, ?, ?)', [abbreviationId, entry['Offset'], getTypes(entry), entry['From'], entry['To']])
|
178
|
+
offset = @Database.last_insert_row_id
|
179
|
+
entry['Timezones'].to_a.each do |timezone|
|
180
|
+
@Database.execute('INSERT INTO `AbbreviationOffset_Timezones` (`Offset`, `Timezone`) VALUES (?, ?)', [offset, @TimezoneIds[timezone]])
|
181
|
+
end
|
182
|
+
entry['Metazones'].to_a.each do |timezone|
|
183
|
+
@Database.execute('INSERT INTO `AbbreviationOffset_Metazones` (`Offset`, `Metazone`) VALUES (?, ?)', [offset, @MetazoneIds[timezone]])
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def loadRailsTimezones
|
190
|
+
@RailsTimezoneIds = {}
|
191
|
+
YAML.load_file(@DataDir + 'rails.yaml').each do |name, timezone|
|
192
|
+
@Database.execute('INSERT INTO `RailsTimezones` (`Name`, `Timezone`) VALUES (?, ?)', [name, @TimezoneIds[timezone]])
|
193
|
+
@RailsTimezoneIds[name] = @Database.last_insert_row_id
|
194
|
+
@Database.execute('INSERT INTO `RailsI18N` (`Locale`, `Name`, `NameLowercase`, `Zone`) VALUES (?, ?, ?, ?)', [getLocaleId('en'), name, name.downcase, @RailsTimezoneIds[name]])
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def loadRailsI18N
|
199
|
+
YAML.load_file(@DataDir + 'rails_i18n.yaml').each do |locale, data|
|
200
|
+
data.each do |name, zone|
|
201
|
+
@Database.execute('INSERT INTO `RailsI18N` (`Locale`, `Name`, `NameLowercase`, `Zone`) VALUES (?, ?, ?, ?)', [getLocaleId(locale), name, name.downcase, @RailsTimezoneIds[zone]])
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def loadWindowsZones
|
207
|
+
@WindowsZoneIds = {}
|
208
|
+
YAML.load_file(@DataDir + 'windows_offsets.yaml').each do |zone, data|
|
209
|
+
@Database.execute('INSERT INTO `WindowsZones` (`Name`, `Standard`, `Daylight`) VALUES (?, ?, ?)', [zone, data['standard'], data['daylight']])
|
210
|
+
@WindowsZoneIds[zone] = @Database.last_insert_row_id
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def loadWindowsZoneTimezones
|
215
|
+
YAML.load_file(@DataDir + 'windows_timezones.yaml').each do |zone, data|
|
216
|
+
unless @WindowsZoneIds.has_key?(zone)
|
217
|
+
puts "Warning! Need to update windows_offsets.yaml! No timezone offset found for '#{zone}'"
|
218
|
+
next
|
219
|
+
end
|
220
|
+
data.each do |territory, entries|
|
221
|
+
entries.each do |timezone|
|
222
|
+
@Database.execute('INSERT INTO `WindowsZone_Timezones` (`Zone`, `Territory`, `Timezone`) VALUES (?, ?, ?)', [@WindowsZoneIds[zone], @TerritoryIds[territory], @TimezoneIds[timezone]])
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def loadWindowsZoneNames
|
229
|
+
YAML.load_file(@DataDir + 'windows_zonenames.yaml').each do |locale, localeData|
|
230
|
+
localeData.each do |name, data|
|
231
|
+
@Database.execute('INSERT INTO `WindowsZoneNames` (`Locale`, `Name`, `NameLowercase`, `Types`) VALUES (?, ?, ?, ?)', [getLocaleId(locale), name, name.downcase, getTypes(data)])
|
232
|
+
nameid = @Database.last_insert_row_id
|
233
|
+
data['Metazones'].to_a.each do |zone|
|
234
|
+
@Database.execute('INSERT INTO `WindowsZoneName_Zones` (`Name`, `Zone`) VALUES (?, ?)', [nameid, @WindowsZoneIds[zone]])
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
@@ -1,172 +1,34 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'date'
|
3
3
|
require 'insensitive_hash'
|
4
|
+
require 'sqlite3'
|
4
5
|
|
5
6
|
module TimezoneParser
|
6
7
|
class Data
|
7
8
|
# Timezone data Storage class
|
8
9
|
class Storage
|
9
10
|
protected
|
10
|
-
@@
|
11
|
-
@@
|
12
|
-
@@TimezoneCountries = nil
|
13
|
-
@@Metazones = nil
|
14
|
-
@@WindowsZones = nil
|
15
|
-
@@WindowsTimezones = nil
|
16
|
-
@@WindowsOffsets = nil
|
17
|
-
@@RailsZones = nil
|
18
|
-
@@RailsTranslated = nil
|
11
|
+
@@Database = nil
|
12
|
+
@@Statements = {}
|
19
13
|
|
20
14
|
public
|
21
15
|
|
22
|
-
|
23
|
-
unless @@Abbreviations
|
24
|
-
@@Abbreviations = Marshal.load(File.open(Data::DataDir + 'abbreviations.dat'))
|
25
|
-
@@Abbreviations.each do |abbr, data|
|
26
|
-
proccessData(data)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
@@Abbreviations
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.Timezones
|
33
|
-
unless @@Timezones
|
34
|
-
@@Timezones = Marshal.load(File.open(Data::DataDir + 'timezones.dat')).insensitive
|
35
|
-
end
|
36
|
-
@@Timezones
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.TimezoneCountries
|
40
|
-
unless @@TimezoneCountries
|
41
|
-
@@TimezoneCountries = Marshal.load(File.open(Data::DataDir + 'countries.dat')).insensitive
|
42
|
-
end
|
43
|
-
@@TimezoneCountries
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.Metazones
|
47
|
-
unless @@Metazones
|
48
|
-
@@Metazones = Marshal.load(File.open(Data::DataDir + 'metazones.dat'))
|
49
|
-
@@Metazones.each do |zone, data|
|
50
|
-
proccessData(data)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
@@Metazones
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.WindowsZones
|
57
|
-
unless @@WindowsZones
|
58
|
-
@@WindowsZones = Marshal.load(File.open(Data::DataDir + 'windows_zonenames.dat')).insensitive
|
59
|
-
end
|
60
|
-
@@WindowsZones
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.WindowsTimezones
|
64
|
-
unless @@WindowsTimezones
|
65
|
-
@@WindowsTimezones = Marshal.load(File.open(Data::DataDir + 'windows_timezones.dat')).insensitive
|
66
|
-
end
|
67
|
-
@@WindowsTimezones
|
68
|
-
end
|
69
|
-
|
70
|
-
def self.WindowsOffsets
|
71
|
-
unless @@WindowsOffsets
|
72
|
-
@@WindowsOffsets = Marshal.load(File.open(Data::DataDir + 'windows_offsets.dat')).insensitive
|
73
|
-
end
|
74
|
-
@@WindowsOffsets
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.RailsZones
|
78
|
-
unless @@RailsZones
|
79
|
-
@@RailsZones = Marshal.load(File.open(Data::DataDir + 'rails.dat')).insensitive
|
80
|
-
end
|
81
|
-
@@RailsZones
|
82
|
-
end
|
83
|
-
|
84
|
-
def self.RailsTranslated
|
85
|
-
unless @@RailsTranslated
|
86
|
-
@@RailsTranslated = Marshal.load(File.open(Data::DataDir + 'rails_i18n.dat')).insensitive
|
87
|
-
end
|
88
|
-
@@RailsTranslated
|
89
|
-
end
|
90
|
-
|
91
|
-
def self.preload(modules)
|
92
|
-
preloaded = false
|
93
|
-
modules.each do |m|
|
94
|
-
case m
|
95
|
-
when :Abbreviations
|
96
|
-
self.Abbreviations
|
97
|
-
self.Metazones
|
98
|
-
preloaded = true
|
99
|
-
when :Timezones
|
100
|
-
self.Timezones
|
101
|
-
self.Metazones
|
102
|
-
preloaded = true
|
103
|
-
when :WindowsZones
|
104
|
-
self.WindowsZones
|
105
|
-
self.WindowsTimezones
|
106
|
-
self.WindowsOffsets
|
107
|
-
preloaded = true
|
108
|
-
when :RailsZones
|
109
|
-
self.RailsZones
|
110
|
-
self.RailsTranslated
|
111
|
-
preloaded = true
|
112
|
-
end
|
113
|
-
end
|
114
|
-
preloaded
|
115
|
-
end
|
116
|
-
|
117
|
-
def self.getTimezones(metazone, toTime, fromTime, regions = [])
|
118
|
-
timezones = SortedSet.new
|
119
|
-
if self.Metazones.has_key?(metazone)
|
120
|
-
entries = Data::loadEntries(self.Metazones[metazone], toTime, fromTime)
|
121
|
-
entries.each do |entry|
|
122
|
-
add = true
|
123
|
-
timezones += entry['Timezones'].select do |timezone|
|
124
|
-
if regions.empty?
|
125
|
-
true
|
126
|
-
else
|
127
|
-
timezoneRegions = self.TimezoneCountries[timezone]
|
128
|
-
timezoneRegions && !(regions & timezoneRegions).empty?
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
timezones
|
134
|
-
end
|
16
|
+
DatabaseName = 'timezones.db'
|
135
17
|
|
136
|
-
def self.
|
137
|
-
|
138
|
-
|
139
|
-
entries = self.WindowsTimezones[zone]
|
140
|
-
regions = entries.keys if regions.empty?
|
141
|
-
regions.each do |region|
|
142
|
-
next unless entries.has_key?(region)
|
143
|
-
timezones += entries[region]
|
144
|
-
end
|
18
|
+
def self.Database
|
19
|
+
unless @@Database
|
20
|
+
@@Database = SQLite3::Database.new((Data::DataDir + DatabaseName).to_s, { readonly: true } )
|
145
21
|
end
|
146
|
-
|
22
|
+
@@Database
|
147
23
|
end
|
148
24
|
|
149
|
-
def self.
|
150
|
-
|
151
|
-
|
152
|
-
data = self.WindowsOffsets[zone]
|
153
|
-
types = [:standard, :daylight] if types.empty?
|
154
|
-
types.each do |type|
|
155
|
-
next unless data.has_key?(type)
|
156
|
-
offsets << data[type]
|
157
|
-
end
|
25
|
+
def self.getStatement(statement)
|
26
|
+
unless @@Statements.has_key?(statement)
|
27
|
+
@@Statements[statement] = self.Database.prepare(statement)
|
158
28
|
end
|
159
|
-
|
29
|
+
@@Statements[statement]
|
160
30
|
end
|
161
31
|
|
162
|
-
protected
|
163
|
-
|
164
|
-
def self.proccessData(data)
|
165
|
-
data.each do |entry|
|
166
|
-
entry['From'] = DateTime.parse(entry['From']) if entry['From']
|
167
|
-
entry['To'] = DateTime.parse(entry['To']) if entry['To']
|
168
|
-
end
|
169
|
-
end
|
170
32
|
end
|
171
33
|
end
|
172
34
|
end
|