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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3142c5391513b96c7862dc7220c1ccd85e4288366a361935054113cc22629594
|
4
|
+
data.tar.gz: 5435d8f578bebcdb8ac8cba258b0a295e6c1b9bb6e0f3c1cdd2c32146150b70f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea39d10652896a5a4c21dca7943f6fc03493206e5286ba06b1ca993112557cf0aa2851470681f45468f676d4740659d5f5ab69cbe9ed40a58f1d276c0d7afce4
|
7
|
+
data.tar.gz: afab3a15077508cc496337d72af6d4d9f9bcf8c86decefa64ba2cd571ba081315b46d318a93ccaa00f4c905c317a5fb77bb10a625a186ae0d3ca1de633e57533
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -102,7 +102,6 @@ code coverage will also be generated
|
|
102
102
|
## Code status
|
103
103
|
[](http://badge.fury.io/rb/TimezoneParser)
|
104
104
|
[](https://travis-ci.org/davispuh/TimezoneParser)
|
105
|
-
[](https://gemnasium.com/davispuh/TimezoneParser)
|
106
105
|
[](https://coveralls.io/r/davispuh/TimezoneParser?branch=master)
|
107
106
|
[](https://codeclimate.com/github/davispuh/TimezoneParser)
|
108
107
|
|
data/Rakefile
CHANGED
@@ -5,6 +5,7 @@ require 'yard'
|
|
5
5
|
require 'yaml'
|
6
6
|
require 'pathname'
|
7
7
|
require 'timezone_parser/data'
|
8
|
+
require 'timezone_parser/data/exporter'
|
8
9
|
|
9
10
|
desc 'Default: run specs.'
|
10
11
|
task :default => :spec
|
@@ -206,10 +207,7 @@ end
|
|
206
207
|
|
207
208
|
desc 'Export data'
|
208
209
|
task 'export' do
|
209
|
-
|
210
|
-
|
211
|
-
'rails.yaml', 'rails_i18n.yaml'].each do |name|
|
212
|
-
path = data_location + name
|
213
|
-
Marshal.dump(YAML.load_file(path), File.open(path.dirname + (path.basename('.*').to_s + '.dat'), 'wb'))
|
214
|
-
end
|
210
|
+
exporter = TimezoneParser::Data::Exporter.new(data_location)
|
211
|
+
exporter.exportDatabase
|
215
212
|
end
|
213
|
+
|
data/TimezoneParser.gemspec
CHANGED
@@ -16,11 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
17
|
spec.files.delete_if { |name| name[-4, 4] == '.yaml' }
|
18
18
|
spec.files << 'data/version.yaml'
|
19
|
-
|
20
|
-
'rails.dat', 'rails_i18n.dat', 'timezones.dat',
|
21
|
-
'windows_offsets.dat', 'windows_timezones.dat', 'windows_zonenames.dat'].each do |name|
|
22
|
-
spec.files << 'data/' + name
|
23
|
-
end
|
19
|
+
spec.files << 'data/timezones.db'
|
24
20
|
|
25
21
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
26
22
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
@@ -28,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
28
24
|
|
29
25
|
spec.add_runtime_dependency 'tzinfo'
|
30
26
|
spec.add_runtime_dependency 'insensitive_hash'
|
27
|
+
spec.add_runtime_dependency 'sqlite3'
|
31
28
|
|
32
29
|
spec.add_development_dependency 'bundler', '>= 1.3'
|
33
30
|
spec.add_development_dependency 'rake'
|
data/data/schema.sql
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
|
2
|
+
CREATE TABLE Timezones (`ID` INTEGER PRIMARY KEY,
|
3
|
+
`Name` TEXT NOT NULL COLLATE NOCASE);
|
4
|
+
CREATE UNIQUE INDEX IDX_Timezones ON Timezones (`Name`);
|
5
|
+
|
6
|
+
|
7
|
+
CREATE TABLE Territories (`ID` INTEGER PRIMARY KEY,
|
8
|
+
`Territory` TEXT NOT NULL COLLATE NOCASE);
|
9
|
+
CREATE UNIQUE INDEX IDX_Territories ON Territories (`Territory`);
|
10
|
+
|
11
|
+
|
12
|
+
CREATE TABLE TerritoryContainment (`ID` INTEGER PRIMARY KEY,
|
13
|
+
`Parent` INTEGER NOT NULL,
|
14
|
+
`Territory` INTEGER NOT NULL,
|
15
|
+
FOREIGN KEY(`Parent`) REFERENCES Territories(`ID`),
|
16
|
+
FOREIGN KEY(`Territory`) REFERENCES Territories(`ID`));
|
17
|
+
CREATE UNIQUE INDEX IDX_TerritoryContainment ON TerritoryContainment (`Parent`, `Territory`);
|
18
|
+
|
19
|
+
|
20
|
+
CREATE TABLE TimezoneTerritories (`ID` INTEGER PRIMARY KEY,
|
21
|
+
`Timezone` INTEGER NOT NULL,
|
22
|
+
`Territory` INTEGER NOT NULL,
|
23
|
+
FOREIGN KEY(`Territory`) REFERENCES Territories(`ID`));
|
24
|
+
CREATE UNIQUE INDEX IDX_TimezoneTerritories ON TimezoneTerritories (`Timezone`, `Territory`);
|
25
|
+
|
26
|
+
|
27
|
+
CREATE TABLE Locales (`ID` INTEGER PRIMARY KEY,
|
28
|
+
`Name` TEXT NOT NULL COLLATE NOCASE,
|
29
|
+
`Parent` INTEGER);
|
30
|
+
CREATE UNIQUE INDEX IDX_Locales ON Locales (`Name`);
|
31
|
+
|
32
|
+
|
33
|
+
CREATE TABLE TimezoneNames (`ID` INTEGER PRIMARY KEY,
|
34
|
+
`Locale` INTEGER NOT NULL,
|
35
|
+
`Name` TEXT NOT NULL COLLATE BINARY,
|
36
|
+
`NameLowercase` TEXT NOT NULL COLLATE NOCASE,
|
37
|
+
`Types` INTEGER,
|
38
|
+
FOREIGN KEY(`Locale`) REFERENCES Locales(`ID`));
|
39
|
+
CREATE UNIQUE INDEX IDX_TimezoneNames ON TimezoneNames (`Locale`, `Name`);
|
40
|
+
CREATE INDEX IDX_TimezoneNamesLowercase ON TimezoneNames (`NameLowercase`);
|
41
|
+
|
42
|
+
|
43
|
+
CREATE TABLE Metazones (`ID` INTEGER PRIMARY KEY,
|
44
|
+
`Name` TEXT NOT NULL COLLATE NOCASE);
|
45
|
+
CREATE UNIQUE INDEX IDX_Metazones ON Metazones (`Name`);
|
46
|
+
|
47
|
+
|
48
|
+
CREATE TABLE MetazonePeriods (`ID` INTEGER PRIMARY KEY,
|
49
|
+
`Metazone` INTEGER NOT NULL,
|
50
|
+
`From` TEXT,
|
51
|
+
`To` TEXT,
|
52
|
+
FOREIGN KEY(`Metazone`) REFERENCES Metazones(`ID`));
|
53
|
+
CREATE UNIQUE INDEX IDX_MetazonePeriods ON MetazonePeriods (`Metazone`, `From`, `To`);
|
54
|
+
|
55
|
+
|
56
|
+
CREATE TABLE MetazonePeriod_Timezones (`ID` INTEGER PRIMARY KEY,
|
57
|
+
`MetazonePeriod` INTEGER NOT NULL,
|
58
|
+
`Timezone` INTEGER NOT NULL,
|
59
|
+
FOREIGN KEY(`MetazonePeriod`) REFERENCES MetazonePeriods(`ID`),
|
60
|
+
FOREIGN KEY(`Timezone`) REFERENCES Timezones(`ID`));
|
61
|
+
CREATE UNIQUE INDEX IDX_MetazonePeriod_Timezones ON MetazonePeriod_Timezones (`MetazonePeriod`, `Timezone`);
|
62
|
+
|
63
|
+
|
64
|
+
CREATE TABLE TimezoneName_Timezones (`ID` INTEGER PRIMARY KEY,
|
65
|
+
`Name` INTEGER NOT NULL,
|
66
|
+
`Timezone` INTEGER NOT NULL,
|
67
|
+
FOREIGN KEY(`Name`) REFERENCES TimezoneNames(`ID`),
|
68
|
+
FOREIGN KEY(`Timezone`) REFERENCES Timezones(`ID`));
|
69
|
+
CREATE UNIQUE INDEX IDX_TimezoneName_Timezones ON TimezoneName_Timezones (`Name`, `Timezone`);
|
70
|
+
|
71
|
+
|
72
|
+
CREATE TABLE TimezoneName_Metazones (`ID` INTEGER PRIMARY KEY,
|
73
|
+
`Name` INTEGER NOT NULL,
|
74
|
+
`Metazone` INTEGER NOT NULL,
|
75
|
+
FOREIGN KEY(`Name`) REFERENCES TimezoneNames(`ID`),
|
76
|
+
FOREIGN KEY(`Metazone`) REFERENCES Metazones(`ID`));
|
77
|
+
CREATE UNIQUE INDEX IDX_TimezoneName_Metazones ON TimezoneName_Metazones (`Name`, `Metazone`);
|
78
|
+
|
79
|
+
|
80
|
+
CREATE TABLE Abbreviations (`ID` INTEGER PRIMARY KEY,
|
81
|
+
`Name` TEXT NOT NULL COLLATE BINARY,
|
82
|
+
`NameLowercase` TEXT NOT NULL COLLATE NOCASE);
|
83
|
+
CREATE UNIQUE INDEX IDX_Abbreviations ON Abbreviations (`Name`);
|
84
|
+
CREATE UNIQUE INDEX IDX_AbbreviationsLowercase ON Abbreviations (`NameLowercase`);
|
85
|
+
|
86
|
+
|
87
|
+
CREATE TABLE AbbreviationOffsets (`ID` INTEGER PRIMARY KEY,
|
88
|
+
`Abbreviation` INTEGER NOT NULL,
|
89
|
+
`Offset` INTEGER,
|
90
|
+
`Types` INTEGER,
|
91
|
+
`From` TEXT,
|
92
|
+
`To` TEXT,
|
93
|
+
FOREIGN KEY(`Abbreviation`) REFERENCES Abbreviations(`ID`));
|
94
|
+
CREATE UNIQUE INDEX IDX_AbbreviationOffsets ON AbbreviationOffsets (`Abbreviation`, `Offset`, `From`, `To`);
|
95
|
+
|
96
|
+
|
97
|
+
CREATE TABLE AbbreviationOffset_Timezones (`ID` INTEGER PRIMARY KEY,
|
98
|
+
`Offset` INTEGER NOT NULL,
|
99
|
+
`Timezone` INTEGER NOT NULL,
|
100
|
+
FOREIGN KEY(`Offset`) REFERENCES AbbreviationOffsets(`ID`),
|
101
|
+
FOREIGN KEY(`Timezone`) REFERENCES Timezones(`ID`));
|
102
|
+
CREATE UNIQUE INDEX IDX_AbbreviationOffset_Timezones ON AbbreviationOffset_Timezones (`Offset`, `Timezone`);
|
103
|
+
|
104
|
+
|
105
|
+
CREATE TABLE AbbreviationOffset_Metazones (`ID` INTEGER PRIMARY KEY,
|
106
|
+
`Offset` INTEGER NOT NULL,
|
107
|
+
`Metazone` INTEGER NOT NULL,
|
108
|
+
FOREIGN KEY(`Offset`) REFERENCES AbbreviationOffsets(`ID`),
|
109
|
+
FOREIGN KEY(`Metazone`) REFERENCES Metazones(`ID`));
|
110
|
+
CREATE UNIQUE INDEX IDX_AbbreviationOffset_Metazones ON AbbreviationOffset_Metazones (`Offset`, `Metazone`);
|
111
|
+
|
112
|
+
|
113
|
+
CREATE TABLE RailsTimezones (`ID` INTEGER PRIMARY KEY,
|
114
|
+
`Name` TEXT NOT NULL COLLATE NOCASE,
|
115
|
+
`Timezone` INTEGER NOT NULL,
|
116
|
+
FOREIGN KEY(`Timezone`) REFERENCES Timezones(`ID`));
|
117
|
+
CREATE UNIQUE INDEX IDX_RailsTimezones ON RailsTimezones (`Name`);
|
118
|
+
|
119
|
+
|
120
|
+
CREATE TABLE RailsI18N (`ID` INTEGER PRIMARY KEY,
|
121
|
+
`Locale` INTEGER NOT NULL,
|
122
|
+
`Name` TEXT NOT NULL COLLATE BINARY,
|
123
|
+
`NameLowercase` TEXT NOT NULL COLLATE NOCASE,
|
124
|
+
`Zone` INTEGER NOT NULL,
|
125
|
+
FOREIGN KEY(`Locale`) REFERENCES Locales(`ID`),
|
126
|
+
FOREIGN KEY(`Zone`) REFERENCES RailsTimezones(`ID`));
|
127
|
+
CREATE UNIQUE INDEX IDX_RailsI18N ON RailsI18N (`Locale`, `Name`);
|
128
|
+
CREATE INDEX IDX_RailsI18NName ON RailsI18N (`NameLowercase`);
|
129
|
+
|
130
|
+
|
131
|
+
CREATE TABLE WindowsZones (`ID` INTEGER PRIMARY KEY,
|
132
|
+
`Name` TEXT NOT NULL COLLATE NOCASE,
|
133
|
+
`Standard` INTEGER NOT NULL,
|
134
|
+
`Daylight` INTEGER NOT NULL);
|
135
|
+
CREATE UNIQUE INDEX IDX_WindowsZones ON WindowsZones (`Name`);
|
136
|
+
|
137
|
+
|
138
|
+
CREATE TABLE WindowsZone_Timezones (`ID` INTEGER PRIMARY KEY,
|
139
|
+
`Zone` INTEGER NOT NULL,
|
140
|
+
`Territory` INTEGER NOT NULL,
|
141
|
+
`Timezone` INTEGER NOT NULL,
|
142
|
+
FOREIGN KEY(`Zone`) REFERENCES WindowsZones(`ID`),
|
143
|
+
FOREIGN KEY(`Territory`) REFERENCES Territories(`ID`),
|
144
|
+
FOREIGN KEY(`Timezone`) REFERENCES Timezones(`ID`));
|
145
|
+
CREATE UNIQUE INDEX IDX_WindowsZone_Timezones ON WindowsZone_Timezones (`Zone`, `Territory`, `Timezone`);
|
146
|
+
|
147
|
+
|
148
|
+
CREATE TABLE WindowsZoneNames (`ID` INTEGER PRIMARY KEY,
|
149
|
+
`Locale` INTEGER NOT NULL,
|
150
|
+
`Name` TEXT NOT NULL COLLATE BINARY,
|
151
|
+
`NameLowercase` TEXT NOT NULL COLLATE NOCASE,
|
152
|
+
`Types` INTEGER,
|
153
|
+
FOREIGN KEY(`Locale`) REFERENCES Locales(`ID`));
|
154
|
+
CREATE UNIQUE INDEX IDX_WindowsZoneNames ON WindowsZoneNames (`Locale`, `Name`);
|
155
|
+
CREATE INDEX IDX_WindowsZoneNamesLowercase ON WindowsZoneNames (`NameLowercase`);
|
156
|
+
|
157
|
+
|
158
|
+
CREATE TABLE WindowsZoneName_Zones (`ID` INTEGER PRIMARY KEY,
|
159
|
+
`Name` INTEGER NOT NULL,
|
160
|
+
`Zone` INTEGER NOT NULL,
|
161
|
+
FOREIGN KEY(`Name`) REFERENCES WindowsZoneNames(`ID`),
|
162
|
+
FOREIGN KEY(`Zone`) REFERENCES WindowsZones(`ID`));
|
163
|
+
CREATE UNIQUE INDEX IDX_WindowsZoneName_Zones ON WindowsZoneName_Zones (`Name`, `Zone`);
|
164
|
+
|
data/lib/timezone_parser.rb
CHANGED
@@ -49,17 +49,6 @@ module TimezoneParser
|
|
49
49
|
@@Locales
|
50
50
|
end
|
51
51
|
|
52
|
-
# Load Timezone data in memory from files
|
53
|
-
#
|
54
|
-
# If no modules are specified it will load default modules
|
55
|
-
# @param modules [Array<Symbol>] list of modules
|
56
|
-
# @see Modules
|
57
|
-
# @see AllModules
|
58
|
-
def self.preload(modules = @@Modules)
|
59
|
-
modules = AllModules if modules.nil? or modules.empty?
|
60
|
-
Data::Storage.preload(modules)
|
61
|
-
end
|
62
|
-
|
63
52
|
# Check if given Timezone name is a valid timezone
|
64
53
|
# @param name [String] either Timezone name or abbreviation
|
65
54
|
# @param locales [Array<String>] check only for these locales
|
@@ -112,13 +101,13 @@ module TimezoneParser
|
|
112
101
|
offsets += Abbreviation::getOffsets(name, toTime, fromTime, regions, type) if modules.include?(:Abbreviations)
|
113
102
|
return offsets.to_a if not all and not offsets.empty?
|
114
103
|
|
115
|
-
offsets += Timezone::getOffsets(name, toTime, fromTime, locales, regions
|
104
|
+
offsets += Timezone::getOffsets(name, toTime, fromTime, locales, regions) if modules.include?(:Timezones)
|
116
105
|
return offsets.to_a if not all and not offsets.empty?
|
117
106
|
|
118
|
-
offsets += WindowsZone::getOffsets(name, locales
|
107
|
+
offsets += WindowsZone::getOffsets(name, locales) if modules.include?(:WindowsZones)
|
119
108
|
return offsets.to_a if not all and not offsets.empty?
|
120
109
|
|
121
|
-
offsets += RailsZone::getOffsets(name, toTime, fromTime, locales
|
110
|
+
offsets += RailsZone::getOffsets(name, toTime, fromTime, locales) if modules.include?(:RailsZones)
|
122
111
|
offsets.to_a
|
123
112
|
end
|
124
113
|
|
@@ -146,13 +135,13 @@ module TimezoneParser
|
|
146
135
|
timezones += Abbreviation::getTimezones(name, toTime, fromTime, regions, type) if modules.include?(:Abbreviations)
|
147
136
|
return timezones.to_a if not all and not timezones.empty?
|
148
137
|
|
149
|
-
timezones += Timezone::getTimezones(name, toTime, fromTime, locales, regions
|
138
|
+
timezones += Timezone::getTimezones(name, toTime, fromTime, locales, regions) if modules.include?(:Timezones)
|
150
139
|
return timezones.to_a if not all and not timezones.empty?
|
151
140
|
|
152
|
-
timezones += WindowsZone::getTimezones(name, locales, regions
|
141
|
+
timezones += WindowsZone::getTimezones(name, locales, regions) if modules.include?(:WindowsZones)
|
153
142
|
return timezones.to_a if not all and not timezones.empty?
|
154
143
|
|
155
|
-
timezones += RailsZone::getTimezones(name, locales
|
144
|
+
timezones += RailsZone::getTimezones(name, locales) if modules.include?(:RailsZones)
|
156
145
|
timezones.to_a
|
157
146
|
end
|
158
147
|
end
|
@@ -23,7 +23,6 @@ module TimezoneParser
|
|
23
23
|
# @param abbreviation [String] Timezone abbreviation
|
24
24
|
def initialize(abbreviation)
|
25
25
|
@Abbreviation = abbreviation
|
26
|
-
@Data = Data.new
|
27
26
|
setTime
|
28
27
|
set(@@Regions.dup, nil)
|
29
28
|
end
|
@@ -42,59 +41,25 @@ module TimezoneParser
|
|
42
41
|
# Check if abbreviation is valid
|
43
42
|
# @return [Boolean] whether abbreviation is valid
|
44
43
|
def isValid?
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
# Abbreviation data
|
49
|
-
# @return [Data] data
|
50
|
-
def getData
|
51
|
-
unless @Loaded
|
52
|
-
@Loaded = true
|
53
|
-
if isValid?
|
54
|
-
data = Data::Storage.Abbreviations[@Abbreviation]
|
55
|
-
if data.count == 1
|
56
|
-
@Data.processEntry(data.first, @ToTime, @FromTime, @Regions)
|
57
|
-
return @Data
|
58
|
-
end
|
59
|
-
entries = Data.filterData(data, @ToTime, @FromTime, @Type, @Regions)
|
60
|
-
entries.each do |entry|
|
61
|
-
@Data.processEntry(entry, @ToTime, @FromTime, @Regions)
|
62
|
-
end
|
63
|
-
return @Data
|
64
|
-
end
|
65
|
-
end
|
66
|
-
@Data
|
67
|
-
end
|
68
|
-
|
69
|
-
# Get UTC offsets in seconds
|
70
|
-
# @return [Array<Fixnum>] list of timezone offsets in seconds
|
71
|
-
def getOffsets
|
72
|
-
unless @Offsets
|
73
|
-
@Offsets = getData.Offsets.to_a
|
74
|
-
if @Offsets.empty? and not getTimezones.empty?
|
75
|
-
types = nil
|
76
|
-
types = [@Type] if @Type
|
77
|
-
@Offsets = @Data.findOffsets(@ToTime, @FromTime, @Regions, types).to_a
|
78
|
-
end
|
44
|
+
if @Valid.nil?
|
45
|
+
sql = 'SELECT 1 FROM `Abbreviations` WHERE `Name` = ? LIMIT 1'
|
46
|
+
@Valid = Data::Storage.getStatement(sql).execute(@Abbreviation).count > 0
|
79
47
|
end
|
80
|
-
@
|
48
|
+
@Valid
|
81
49
|
end
|
82
50
|
|
83
51
|
# Check if given Timezone abbreviation (case-sensitive) is a valid timezone
|
84
52
|
# @param abbreviation [String] Timezone abbreviation
|
85
53
|
# @return [Boolean] whether Timezone is valid
|
86
54
|
def self.isValid?(abbreviation)
|
87
|
-
Data::Storage.Abbreviations.
|
55
|
+
Data::Storage.getStatement('SELECT 1 FROM `Abbreviations` WHERE `Name` = ? LIMIT 1').execute(abbreviation).count > 0
|
88
56
|
end
|
89
57
|
|
90
58
|
# Check if given Timezone abbreviation (case-insensitive) could be a valid timezone
|
91
59
|
# @param abbreviation [String] Timezone abbreviation to check for
|
92
60
|
# @return [Boolean] whether Timezone is valid
|
93
61
|
def self.couldBeValid?(abbreviation)
|
94
|
-
Data::Storage.Abbreviations.
|
95
|
-
return true if abbr.casecmp(abbreviation).zero?
|
96
|
-
end
|
97
|
-
false
|
62
|
+
Data::Storage.getStatement('SELECT 1 FROM `Abbreviations` WHERE `NameLowercase` = ? LIMIT 1').execute(abbreviation.downcase).count > 0
|
98
63
|
end
|
99
64
|
|
100
65
|
# Get UTC offsets in seconds for given Timezone abbreviation
|
@@ -126,5 +91,111 @@ module TimezoneParser
|
|
126
91
|
def self.getMetazones(abbreviation)
|
127
92
|
self.new(abbreviation).getMetazones
|
128
93
|
end
|
94
|
+
|
95
|
+
protected
|
96
|
+
|
97
|
+
def getFilteredData(dataType)
|
98
|
+
types = nil
|
99
|
+
types = [@Type] if @Type
|
100
|
+
|
101
|
+
params = [@Abbreviation.downcase]
|
102
|
+
column = nil
|
103
|
+
joins = ' INNER JOIN `AbbreviationOffsets` AS O ON O.Abbreviation = A.ID'
|
104
|
+
regionJoins = ''
|
105
|
+
useMetazonePeriodFilter = false
|
106
|
+
case dataType
|
107
|
+
when :Offsets, :Timezones
|
108
|
+
column = '`Timezones`.`Name`'
|
109
|
+
if dataType == :Offsets
|
110
|
+
column = 'O.`Offset`, `Timezones`.`Name`, O.`Types`'
|
111
|
+
end
|
112
|
+
joins += ' LEFT JOIN `AbbreviationOffset_Timezones` AS T ON T.Offset = O.ID'
|
113
|
+
joins += ' LEFT JOIN `AbbreviationOffset_Metazones` AS M ON M.Offset = O.ID'
|
114
|
+
joins += ' LEFT JOIN `MetazonePeriods` MP ON M.Metazone = MP.Metazone'
|
115
|
+
joins += ' LEFT JOIN `MetazonePeriod_Timezones` MPT ON MPT.MetazonePeriod = MP.ID'
|
116
|
+
joins += ' LEFT JOIN `Timezones` ON (T.Timezone = Timezones.ID OR MPT.Timezone = Timezones.ID)'
|
117
|
+
regionJoins += ' LEFT JOIN `TimezoneTerritories` ON (TimezoneTerritories.Timezone = T.Timezone OR TimezoneTerritories.Timezone = MPT.Timezone)'
|
118
|
+
regionJoins += ' LEFT JOIN `Territories` ON TimezoneTerritories.Territory = Territories.ID'
|
119
|
+
useMetazonePeriodFilter = true
|
120
|
+
when :Metazones
|
121
|
+
column = '`Metazones`.`Name`'
|
122
|
+
joins += ' INNER JOIN `AbbreviationOffset_Metazones` AS M ON M.Offset = O.ID'
|
123
|
+
joins += ' INNER JOIN `Metazones` ON M.Metazone = Metazones.ID'
|
124
|
+
regionJoins += ' LEFT JOIN `AbbreviationOffset_Timezones` AS T ON T.Offset = O.ID'
|
125
|
+
regionJoins += ' LEFT JOIN `TimezoneTerritories` ON TimezoneTerritories.Timezone = T.Timezone'
|
126
|
+
regionJoins += ' LEFT JOIN `Territories` ON TimezoneTerritories.Territory = Territories.ID'
|
127
|
+
when :Types
|
128
|
+
column = 'O.`Types`'
|
129
|
+
else
|
130
|
+
raise StandardError, "Unkown dataType '#{dataType}'"
|
131
|
+
end
|
132
|
+
sql = 'SELECT DISTINCT ' + column + ' FROM `Abbreviations` AS A'
|
133
|
+
sql += joins
|
134
|
+
if not @Regions.nil? and not @Regions.empty?
|
135
|
+
sql += regionJoins
|
136
|
+
end
|
137
|
+
sql += ' WHERE A.`NameLowercase` = ?'
|
138
|
+
if not types.nil?
|
139
|
+
if types.include?(:standard) and not types.include?(:daylight)
|
140
|
+
sql += ' AND (O.`Types` & ?) > 0'
|
141
|
+
params << TIMEZONE_TYPE_STANDARD
|
142
|
+
|
143
|
+
else
|
144
|
+
sql += ' AND (O.`Types` & ?) > 0'
|
145
|
+
params << TIMEZONE_TYPE_DAYLIGHT
|
146
|
+
end
|
147
|
+
end
|
148
|
+
unless @FromTime.nil?
|
149
|
+
fromsql = '((O.`From` IS NULL AND O.`To` > ?) OR (O.`To` IS NULL AND O.`From` <= ?) OR (O.`From` <= ? AND O.`To` > ?) OR (O.`From` IS NULL AND O.`To` IS NULL))'
|
150
|
+
params += Array.new(4, @FromTime.to_s)
|
151
|
+
if useMetazonePeriodFilter
|
152
|
+
fromsql = '(' + fromsql + ' AND ((MP.`From` IS NULL AND MP.`To` > ?) OR (MP.`To` IS NULL AND MP.`From` <= ?) OR (MP.`From` <= ? AND MP.`To` > ?) OR (MP.`From` IS NULL AND MP.`To` IS NULL)))'
|
153
|
+
params += Array.new(4, @FromTime.to_s)
|
154
|
+
end
|
155
|
+
if @ToTime.nil?
|
156
|
+
sql += ' AND ' + fromsql
|
157
|
+
end
|
158
|
+
end
|
159
|
+
unless @ToTime.nil?
|
160
|
+
tosql = '((O.`From` IS NULL AND O.`To` >= ?) OR (O.`To` IS NULL AND O.`From` < ?) OR (O.`From` < ? AND O.`To` >= ?) OR (O.`From` IS NULL AND O.`To` IS NULL))'
|
161
|
+
params += Array.new(4, @ToTime.to_s)
|
162
|
+
if useMetazonePeriodFilter
|
163
|
+
tosql = '(' + tosql + ' AND ((MP.`From` IS NULL AND MP.`To` >= ?) OR (MP.`To` IS NULL AND MP.`From` < ?) OR (MP.`From` < ? AND MP.`To` >= ?) OR (MP.`From` IS NULL AND MP.`To` IS NULL)))'
|
164
|
+
params += Array.new(4, @ToTime.to_s)
|
165
|
+
end
|
166
|
+
if not @FromTime.nil?
|
167
|
+
sql += ' AND ((' + fromsql + ') OR (' + tosql + '))'
|
168
|
+
else
|
169
|
+
sql += ' AND ' + tosql
|
170
|
+
end
|
171
|
+
end
|
172
|
+
if not @Regions.nil? and not @Regions.empty?
|
173
|
+
sql += ' AND Territories.Territory IN (' + Array.new(@Regions.count, '?').join(',') + ')'
|
174
|
+
params += @Regions
|
175
|
+
end
|
176
|
+
sql += ' ORDER BY ' + column
|
177
|
+
if dataType == :Offsets
|
178
|
+
result = Set.new
|
179
|
+
timezonesTypes = []
|
180
|
+
Data::Storage.getStatement(sql).execute(*params).each do |row|
|
181
|
+
if row.first.nil?
|
182
|
+
timezonesTypes << [row[1], row[2]]
|
183
|
+
else
|
184
|
+
result << row.first
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
result += self.class.findOffsetsFromTimezonesTypes(timezonesTypes, @ToTime, @FromTime, types) if result.empty?
|
189
|
+
|
190
|
+
result = result.sort
|
191
|
+
else
|
192
|
+
result = Data::Storage.getStatement(sql).execute(*params).collect { |row| row.first }
|
193
|
+
if dataType == :Types
|
194
|
+
result = self.class.convertTypes(result)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
result
|
198
|
+
end
|
199
|
+
|
129
200
|
end
|
130
201
|
end
|