TimezoneParser 0.4.0 → 1.0.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/.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
|