ziptz 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bb930df6f8932cd9123377c28e9f0d7e2ef3e789
4
+ data.tar.gz: 9d787ed2c6559b2667bc655611dce94365508512
5
+ SHA512:
6
+ metadata.gz: 832a18781ef3bdef3e06ba98ad0bcd5b9c1a32a846babcaa76d04705315aadc2f3e215d6bbf0c2fad0ee3b92b04f7387c56bf094330ab1e6740cdc32aacd8013
7
+ data.tar.gz: 879033d897582ae100bd66d0253424b1e617306cf762d4e6dc4360af5b5770a87828e1cd1638fe19cd9634bf699d4ba3bc85409181f326295b4fe27b56169e0d
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ gemspec
2
+ source 'https://rubygems.org'
3
+
4
+ group :development, :test do
5
+ gem 'activerecord'
6
+ gem 'mysql2'
7
+ gem 'rspec'
8
+ gem 'guard'
9
+ gem 'guard-rspec'
10
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,97 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ziptz (1.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activemodel (4.2.1)
10
+ activesupport (= 4.2.1)
11
+ builder (~> 3.1)
12
+ activerecord (4.2.1)
13
+ activemodel (= 4.2.1)
14
+ activesupport (= 4.2.1)
15
+ arel (~> 6.0)
16
+ activesupport (4.2.1)
17
+ i18n (~> 0.7)
18
+ json (~> 1.7, >= 1.7.7)
19
+ minitest (~> 5.1)
20
+ thread_safe (~> 0.3, >= 0.3.4)
21
+ tzinfo (~> 1.1)
22
+ arel (6.0.0)
23
+ builder (3.2.2)
24
+ celluloid (0.16.0)
25
+ timers (~> 4.0.0)
26
+ coderay (1.1.0)
27
+ diff-lcs (1.2.5)
28
+ ffi (1.9.8)
29
+ formatador (0.2.5)
30
+ guard (2.12.5)
31
+ formatador (>= 0.2.4)
32
+ listen (~> 2.7)
33
+ lumberjack (~> 1.0)
34
+ nenv (~> 0.1)
35
+ notiffany (~> 0.0)
36
+ pry (>= 0.9.12)
37
+ shellany (~> 0.0)
38
+ thor (>= 0.18.1)
39
+ guard-compat (1.2.1)
40
+ guard-rspec (4.5.1)
41
+ guard (~> 2.1)
42
+ guard-compat (~> 1.1)
43
+ rspec (>= 2.99.0, < 4.0)
44
+ hitimes (1.2.2)
45
+ i18n (0.7.0)
46
+ json (1.8.2)
47
+ listen (2.10.0)
48
+ celluloid (~> 0.16.0)
49
+ rb-fsevent (>= 0.9.3)
50
+ rb-inotify (>= 0.9)
51
+ lumberjack (1.0.9)
52
+ method_source (0.8.2)
53
+ minitest (5.7.0)
54
+ mysql2 (0.3.18)
55
+ nenv (0.2.0)
56
+ notiffany (0.0.6)
57
+ nenv (~> 0.1)
58
+ shellany (~> 0.0)
59
+ pry (0.10.1)
60
+ coderay (~> 1.1.0)
61
+ method_source (~> 0.8.1)
62
+ slop (~> 3.4)
63
+ rb-fsevent (0.9.5)
64
+ rb-inotify (0.9.5)
65
+ ffi (>= 0.5.0)
66
+ rspec (3.2.0)
67
+ rspec-core (~> 3.2.0)
68
+ rspec-expectations (~> 3.2.0)
69
+ rspec-mocks (~> 3.2.0)
70
+ rspec-core (3.2.3)
71
+ rspec-support (~> 3.2.0)
72
+ rspec-expectations (3.2.1)
73
+ diff-lcs (>= 1.2.0, < 2.0)
74
+ rspec-support (~> 3.2.0)
75
+ rspec-mocks (3.2.1)
76
+ diff-lcs (>= 1.2.0, < 2.0)
77
+ rspec-support (~> 3.2.0)
78
+ rspec-support (3.2.2)
79
+ shellany (0.0.1)
80
+ slop (3.6.0)
81
+ thor (0.19.1)
82
+ thread_safe (0.3.5)
83
+ timers (4.0.1)
84
+ hitimes
85
+ tzinfo (1.2.2)
86
+ thread_safe (~> 0.1)
87
+
88
+ PLATFORMS
89
+ ruby
90
+
91
+ DEPENDENCIES
92
+ activerecord
93
+ guard
94
+ guard-rspec
95
+ mysql2
96
+ rspec
97
+ ziptz!
data/Gemfile.travis ADDED
@@ -0,0 +1,6 @@
1
+ gemspec
2
+ source 'https://rubygems.org'
3
+
4
+ group :test do
5
+ gem 'rspec'
6
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2014-2015 Keith Morrison <keithm@infused.org>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # Ziptz
2
+ <!-- [![Version](http://img.shields.io/gem/v/ziptz.svg?style=flat)](https://rubygems.org/gems/ziptz) -->
3
+ [![Build Status](http://img.shields.io/travis/infused/ziptz/master.svg?style=flat)](http://travis-ci.org/infused/ziptz)
4
+ [![Issues](https://img.shields.io/github/issues/infused/ziptz.svg)](https://github.com/infused/ziptz/issues)
5
+ [![Total Downloads](https://img.shields.io/gem/dt/ziptz.svg)](https://rubygems.org/gems/ziptz/)
6
+
7
+ Get the time zone for any US ZIP code.
8
+
9
+ <i>ZIP codes are up to date as of <b>June 2015</b>.</i>
10
+
11
+ ## Installation
12
+
13
+ Add the gem to your Gemfile:
14
+
15
+ gem 'ziptz'
16
+
17
+
18
+ ## Usage
19
+
20
+ Get the time zone name for any ZIP code:
21
+
22
+ z = Ziptz.new
23
+ z.time_zone_name('97213') #=> "Pacific"
24
+
25
+ Get the time zone offset for any ZIP code:
26
+
27
+ z.time_zone_offset('97213') #=> -8
28
+
29
+ <i>Please note that offsets do not include daylight savings time.<i>
30
+
31
+
32
+ Get all the zip codes in a time zone:
33
+
34
+ z.zips('American Samoa') #=> ["96799", "96941", "96942", "96943", "96944"]
35
+
36
+
37
+ ## Supported Time Zones
38
+
39
+ * "Mountain" GMT -07:00
40
+ * "Pacific" GMT -08:00
41
+ * "Alaska" GMT -09:00
42
+ * "Hawaii-Aleutian Islands" GMT -10:00
43
+ * "American Samoa" GMT -11:00
44
+ * "Marshall Islands" GMT +12:00
45
+ * "Guam" GMT +10:00
46
+ * "Palau" GMT +09:00
47
+
48
+ ## License
49
+
50
+ Copyright (c) 2015 Keith Morrison <<keithm@infused.org>>
51
+
52
+ Permission is hereby granted, free of charge, to any person
53
+ obtaining a copy of this software and associated documentation
54
+ files (the "Software"), to deal in the Software without
55
+ restriction, including without limitation the rights to use,
56
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
57
+ copies of the Software, and to permit persons to whom the
58
+ Software is furnished to do so, subject to the following
59
+ conditions:
60
+
61
+ The above copyright notice and this permission notice shall be
62
+ included in all copies or substantial portions of the Software.
63
+
64
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
65
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
66
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
67
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
68
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
69
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
70
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
71
+ OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ require 'bundler/setup';
2
+ Bundler.setup(:default, :development)
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new :spec do |t|
6
+ t.rspec_opts = %w(--color)
7
+ end
8
+
9
+ RSpec::Core::RakeTask.new :specdoc do |t|
10
+ t.rspec_opts = %w(-fl)
11
+ end
12
+
13
+ task :default => :spec
14
+
15
+ desc "Open an irb session preloaded with this library"
16
+ task :console do
17
+ sh "irb -rubygems -I lib -r ziptz.rb"
18
+ end
19
+
20
+ desc 'Create ziptz.yml from zipcodes database'
21
+ task :create_ziptz do
22
+ require 'yaml'
23
+ require 'active_record'
24
+
25
+ db_config = YAML::load(File.open('database.yml'))
26
+ ActiveRecord::Base.establish_connection(db_config)
27
+
28
+ class ZipCode < ActiveRecord::Base
29
+ self.table_name = 'ZIPCodes'
30
+ self.primary_key = 'ZipCode'
31
+
32
+ alias_attribute :zip_code, :ZipCode
33
+ alias_attribute :time_zone, :TimeZone
34
+ end
35
+
36
+ puts "Retrieving zip codes from database"
37
+
38
+ data = {}
39
+ ZipCode.find_each do |zip|
40
+ data[zip.zip_code] ||= zip.time_zone
41
+ end
42
+
43
+ puts "Writing ziptz.data"
44
+
45
+ lines = data.map {|k, v| "#{k}=#{v}"}
46
+ lines.sort!
47
+
48
+ File.open('ziptz.data', 'w') do |f|
49
+ lines.each {|line| f.puts line}
50
+ end
51
+
52
+ end
data/database.yml ADDED
@@ -0,0 +1,3 @@
1
+ adapter: mysql2
2
+ username: root
3
+ database: zip_codes
@@ -0,0 +1,3 @@
1
+ module ZipTZ
2
+ VERSION = '1.0.0'
3
+ end
data/lib/ziptz.rb ADDED
@@ -0,0 +1,65 @@
1
+ require 'yaml'
2
+
3
+ class Ziptz
4
+ TZ_INFO = {
5
+ '4' => {name: 'Atlantic', offset: -4},
6
+ '5' => {name: 'Eastern', offset: -5},
7
+ '6' => {name: 'Central', offset: -6},
8
+ '7' => {name: 'Mountain', offset: -7},
9
+ '8' => {name: 'Pacific', offset: -8},
10
+ '9' => {name: 'Alaska', offset: -9},
11
+ '10' => {name: 'Hawaii-Aleutian Islands', offset: -10},
12
+ '11' => {name: 'American Samoa', offset: -11},
13
+ '13' => {name: 'Marshall Islands', offset: 12},
14
+ '14' => {name: 'Guam', offset: 10},
15
+ '15' => {name: 'Palau', offset: 9}
16
+ }
17
+
18
+ def initialize
19
+ @zips = load_data
20
+ end
21
+
22
+ def time_zone_name(zip)
23
+ hash = time_zone_hash(zip)
24
+ hash && hash[:name]
25
+ end
26
+
27
+ def time_zone_offset(zip)
28
+ tz = time_zone_hash(zip)
29
+ tz && tz[:offset]
30
+ end
31
+
32
+ def zips(tz_name)
33
+ tz_code = tz_name_to_code[tz_name.downcase]
34
+ tz_code && zips_by_code(tz_code)
35
+ end
36
+
37
+ protected
38
+
39
+ def zips_by_code(tz_code)
40
+ selected = @zips.select { |_, v| v == tz_code.to_s }
41
+ selected.keys.sort
42
+ end
43
+
44
+ def time_zone_hash(zip)
45
+ TZ_INFO[@zips[zip.to_s]]
46
+ end
47
+
48
+ def tz_name_to_code
49
+ @tz_name_to_code ||= TZ_INFO.inject({}) do |data, (code, tz)|
50
+ data[tz[:name].downcase] = code
51
+ data
52
+ end
53
+ end
54
+
55
+ def data_path
56
+ File.join(File.dirname(__FILE__), '..', 'ziptz.data')
57
+ end
58
+
59
+ def load_data
60
+ File.foreach(data_path).with_object({}) do |line, data|
61
+ zip, tz = line.split('=').map(&:strip)
62
+ data[zip] = tz
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,9 @@
1
+ require 'ziptz'
2
+ require 'yaml'
3
+ require 'rspec'
4
+
5
+ Encoding.default_external = 'UTF-8' if defined?(Encoding)
6
+
7
+ RSpec.configure do |config|
8
+
9
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ziptz do
4
+ describe '#time_zone_name' do
5
+ let(:ziptz) { Ziptz.new }
6
+
7
+ context 'when given a 5-digit zipcode' do
8
+ it 'returns the time zone number' do
9
+ expect(ziptz.time_zone_name('97034')).to eq 'Pacific'
10
+ end
11
+ end
12
+
13
+ context 'when there is no matching zipcode' do
14
+ it 'returns nil' do
15
+ expect(ziptz.time_zone_name('xyz')).to be_nil
16
+ end
17
+ end
18
+ end
19
+
20
+ describe '#time_zone_offset' do
21
+ let(:ziptz) { Ziptz.new }
22
+
23
+ context 'when given a 5-digit zipcode' do
24
+ it 'returns the time zone number' do
25
+ expect(ziptz.time_zone_offset('97034')).to eq -8
26
+ end
27
+ end
28
+
29
+ context 'when there is no matching zipcode' do
30
+ it 'returns nil' do
31
+ expect(ziptz.time_zone_offset('xyz')).to be_nil
32
+ end
33
+ end
34
+ end
35
+
36
+ describe '#zips' do
37
+ context 'when given a time zone' do
38
+ let(:ziptz) { Ziptz.new }
39
+
40
+ it 'returns an array of zip codes' do
41
+ expect(ziptz.zips('American Samoa')).to eq %w(96799 96941 96942 96943 96944)
42
+ end
43
+
44
+ it 'is case-insensitive' do
45
+ expect(ziptz.zips('american samoa')).to eq %w(96799 96941 96942 96943 96944)
46
+ end
47
+
48
+ it 'returns nil for unknown time zones' do
49
+ expect(ziptz.zips('Glark')).to be_nil
50
+ end
51
+ end
52
+ end
53
+ end