ziptz 2.0.17 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/zip_code.rb ADDED
@@ -0,0 +1,68 @@
1
+ require 'active_record'
2
+ require 'tty-spinner'
3
+ require 'yaml'
4
+ require 'ziptz'
5
+
6
+ class ZipCode < ActiveRecord::Base
7
+ self.table_name = 'ZIPCodes'
8
+ self.primary_key = 'ZipCode'
9
+ establish_connection YAML.safe_load(File.open('database.yml'))
10
+
11
+ alias_attribute :day_light_saving, :DayLightSaving
12
+ alias_attribute :state, :State
13
+ alias_attribute :time_zone, :TimeZone
14
+ alias_attribute :zip_code, :ZipCode
15
+
16
+ def self.import
17
+ spinner = TTY::Spinner.new('[:spinner] Retrieving zip codes from database')
18
+ spinner.auto_spin
19
+
20
+ spinner = TTY::Spinner.new('[:spinner] :message')
21
+ spinner.update message: 'Retrieving zip codes from database'
22
+ data = {}
23
+ ZipCode.find_each do |zip|
24
+ next if zip.time_zone.blank? || zip.day_light_saving.blank?
25
+
26
+ data[zip.zip_code] ||= {}
27
+ data[zip.zip_code][:tz] ||= begin
28
+ if zip.state == 'AZ' && zip.day_light_saving == 'N'
29
+ 'America/Phoenix'
30
+ elsif zip.state == 'AK' && zip.time_zone == '10'
31
+ 'America/Adak'
32
+ else
33
+ Ziptz::TZ_INFO[zip.time_zone][:name]
34
+ end
35
+ end
36
+ data[zip.zip_code][:dst] ||= zip.day_light_saving
37
+ end
38
+ spinner.update message: "Retrieving zip codes from database (#{data.size} records)"
39
+ spinner.success
40
+
41
+ spinner = TTY::Spinner.new('[:spinner] :message')
42
+ spinner.update message: 'Writing tz.data'
43
+ spinner.auto_spin
44
+ lines = data.map { |k, v| "#{k}=#{v[:tz]}" }
45
+ lines.sort!
46
+ File.open('data/tz.data', 'w') do |f|
47
+ lines.each { |line| f.puts line }
48
+ end
49
+ spinner.update message: "Writing tz.data (#{File.size('data/tz.data')} bytes)"
50
+ spinner.success
51
+ # puts File.size('data/tz.data').to_s
52
+
53
+ spinner = TTY::Spinner.new('[:spinner] :message')
54
+ spinner.update message: 'Writing dst.data'
55
+ spinner.auto_spin
56
+ lines = data.map { |k, v| "#{k}=#{v[:dst] =~ /y/i ? 1 : 0}" }
57
+ lines.sort!
58
+
59
+ File.open('data/dst.data', 'w') do |f|
60
+ lines.each { |line| f.puts line }
61
+ end
62
+ spinner.update message: "Writing dst.data (#{File.size('data/dst.data')} bytes)"
63
+ spinner.success
64
+ rescue StandardError
65
+ spinner && spinner.error
66
+ raise
67
+ end
68
+ end
data/lib/ziptz.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'yaml'
2
2
 
3
3
  class Ziptz
4
- VERSION = '2.0.17'.freeze
4
+ VERSION = '2.1.0'.freeze
5
5
 
6
6
  TZ_INFO = {
7
7
  '0' => {name: 'APO/FPO (time zone unknown)', offset: 0},
@@ -16,12 +16,13 @@ class Ziptz
16
16
  '13' => {name: 'Pacific/Majuro', offset: 12},
17
17
  '14' => {name: 'Pacific/Guam', offset: 10},
18
18
  '15' => {name: 'Pacific/Palau', offset: 9},
19
- '16' => {name: 'Pacific/Pohnpei', offset: 11}
19
+ '16' => {name: 'Pacific/Pohnpei', offset: 11},
20
+ 'AZ' => {name: 'America/Phoenix', offset: -7},
21
+ 'AD' => {name: 'America/Adak', offset: -10}
20
22
  }.freeze
21
23
 
22
24
  def time_zone_name(zip)
23
- hash = time_zone_info(zip)
24
- hash && hash[:name]
25
+ get_time_zone(zip)
25
26
  end
26
27
 
27
28
  def time_zone_offset(zip)
@@ -34,8 +35,7 @@ class Ziptz
34
35
  end
35
36
 
36
37
  def zips(tz_name)
37
- tz_code = tz_name_to_code[tz_name.downcase]
38
- tz_code && zips_by_code(tz_code)
38
+ zips_by_code(tz_name)
39
39
  end
40
40
 
41
41
  def inspect
@@ -53,24 +53,17 @@ class Ziptz
53
53
  end
54
54
 
55
55
  def zips_by_code(tz_code)
56
- tz.select { |_, v| v == tz_code.to_s }.keys.sort
56
+ tz.select { |_, v| v.match /#{tz_code}/i }.keys.sort
57
57
  end
58
58
 
59
59
  def time_zone_info(zip)
60
- TZ_INFO[get_time_zone(zip)]
60
+ TZ_INFO.values.detect { |v| v[:name] == get_time_zone(zip) }
61
61
  end
62
62
 
63
63
  def get_time_zone(zip)
64
64
  tz[zip.to_s.slice(0, 5)]
65
65
  end
66
66
 
67
- def tz_name_to_code
68
- @tz_name_to_code ||= TZ_INFO.each_with_object({}) do |(code, tz), data|
69
- name = tz[:name].downcase
70
- data[name] = code
71
- end
72
- end
73
-
74
67
  def tz_data_path
75
68
  File.join(File.dirname(__FILE__), '..', 'data', 'tz.data')
76
69
  end
data/spec/ziptz_spec.rb CHANGED
@@ -29,15 +29,27 @@ RSpec.describe Ziptz do
29
29
  end
30
30
  end
31
31
 
32
- describe '#time_zone_uses_dst?' do
32
+ describe '#time_zone_name' do
33
33
  context 'when given a 5-digit zipcode' do
34
34
  it 'returns the time zone number' do
35
35
  expect(ziptz.time_zone_name('97034')).to eq 'America/Los_Angeles'
36
36
  end
37
37
  end
38
+
39
+ context 'when given a 9-digit zipcode' do
40
+ it 'returns the time zone number' do
41
+ expect(ziptz.time_zone_name('97034-1234')).to eq 'America/Los_Angeles'
42
+ end
43
+ end
44
+
45
+ context 'when there is no matching zipcode' do
46
+ it 'returns nil' do
47
+ expect(ziptz.time_zone_name('xyz')).to be_nil
48
+ end
49
+ end
38
50
  end
39
51
 
40
- describe '#time_zone_offset' do
52
+ describe '#time_zone_uses_dst?' do
41
53
  context 'when given a 5-digit zipcode' do
42
54
  it 'returns a boolean' do
43
55
  expect(ziptz.time_zone_uses_dst?('97034')).to eq true
@@ -52,6 +64,26 @@ RSpec.describe Ziptz do
52
64
  end
53
65
  end
54
66
 
67
+ context 'when there is no matching zipcode' do
68
+ it 'returns nil' do
69
+ expect(ziptz.time_zone_uses_dst?('xyz')).to be_nil
70
+ end
71
+ end
72
+ end
73
+
74
+ describe '#time_zone_offset' do
75
+ context 'when given a 5-digit zipcode' do
76
+ it 'returns the time zone number' do
77
+ expect(ziptz.time_zone_offset('97034')).to eq(-8)
78
+ end
79
+ end
80
+
81
+ context 'when given a 9-digit zipcode' do
82
+ it 'returns the time zone number' do
83
+ expect(ziptz.time_zone_offset('97034-1234')).to eq(-8)
84
+ end
85
+ end
86
+
55
87
  context 'when there is no matching zipcode' do
56
88
  it 'returns nil' do
57
89
  expect(ziptz.time_zone_offset('xyz')).to be_nil
@@ -69,8 +101,8 @@ RSpec.describe Ziptz do
69
101
  expect(ziptz.zips('pacific/pago_pago')).to eq %w[96799]
70
102
  end
71
103
 
72
- it 'returns nil for unknown time zones' do
73
- expect(ziptz.zips('Glark')).to be_nil
104
+ it 'returns empty array for unknown time zones' do
105
+ expect(ziptz.zips('Glark')).to be_empty
74
106
  end
75
107
  end
76
108
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ziptz
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.17
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-02 00:00:00.000000000 Z
11
+ date: 2019-10-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Get timezone info for all 5-digit US zip codes
14
14
  email: keithm@infused.org
@@ -27,6 +27,7 @@ files:
27
27
  - Rakefile
28
28
  - data/dst.data
29
29
  - data/tz.data
30
+ - lib/zip_code.rb
30
31
  - lib/ziptz.rb
31
32
  - spec/spec_helper.rb
32
33
  - spec/ziptz_spec.rb