ziptz 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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