tz_lookup_wrapper 0.0.4

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.
@@ -0,0 +1,32 @@
1
+ require "tz_lookup_wrapper/version"
2
+ require "tz_lookup_wrapper/active_support"
3
+
4
+ module TzLookupWrapper
5
+ class TzLookupWrapperException < Exception;end
6
+
7
+ TZ_LOOKUP_PATH="#{File.dirname(__FILE__)}/../vendor/tz-lookup/index.js"
8
+
9
+ def self.lookup(lat_r,lng_r)
10
+ lat = Float lat_r
11
+ lng = Float lng_r
12
+ script = <<HEREDOC
13
+ try {
14
+ process.stdout.write(require("#{TZ_LOOKUP_PATH}")(#{lat}, #{lng}));
15
+ } catch (ex) {
16
+ process.stdout.write(ex.message);
17
+ process.exit(code=1)
18
+ }
19
+ HEREDOC
20
+ result = nil
21
+ IO.popen('node', 'r+') do |io|
22
+ io.puts(script)
23
+ io.close_write
24
+ result = io.gets
25
+ end
26
+ if $?.success?
27
+ result
28
+ else
29
+ raise TzLookupWrapperException.new result || "Empty output"
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe TzLookupWrapper::DetectNode do
4
+
5
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe TzLookupWrapper do
4
+ it "should lookup coordinates" do
5
+ expect(TzLookupWrapper.lookup(43.7, -79.4)).to eq("America/Toronto")
6
+ end
7
+
8
+ it "should format tzinfo to long timezone" do
9
+ expect(TzLookupWrapper::ActiveSupport.format("America/Toronto")).to eq("Eastern Time (US & Canada)")
10
+ end
11
+ end
@@ -0,0 +1 @@
1
+ require 'tz_lookup_wrapper'
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tz_lookup_wrapper/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tz_lookup_wrapper"
8
+ spec.version = TzLookupWrapper::VERSION
9
+ spec.authors = ["Rajitha Perera"]
10
+ spec.email = ["rajiteh@gmail.com"]
11
+ spec.summary = %q{Ruby wrapper for tz-lookup npm package.}
12
+ spec.homepage = "https://github.com/rajiteh/tz_lookup_wrapper"
13
+ spec.license = "CC0"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+
17
+ # http://somethingaboutcode.wordpress.com/2012/09/27/include-files-from-git-submodules-when-building-a-ruby-gem/
18
+ # get an array of submodule dirs by executing 'pwd' inside each submodule
19
+ gem_dir = File.expand_path(File.dirname(__FILE__)) + "/"
20
+ `git submodule --quiet foreach pwd`.split($\).each do |submodule_path|
21
+ Dir.chdir(submodule_path) do
22
+ submodule_relative_path = submodule_path.sub gem_dir, ""
23
+ # issue git ls-files in submodule's directory and
24
+ # prepend the submodule path to create absolute file paths
25
+ `git ls-files`.split($\).each do |filename|
26
+ spec.files << "#{submodule_relative_path}/#{filename}"
27
+ end
28
+ end
29
+ end
30
+
31
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
32
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
33
+ spec.require_paths = ["lib"]
34
+
35
+ spec.add_development_dependency "bundler", "~> 1.7"
36
+ spec.add_development_dependency "rake", "~> 10.0"
37
+ spec.add_development_dependency "rspec"
38
+ end
@@ -0,0 +1,2 @@
1
+ /node_modules
2
+ /tz_world.json
@@ -0,0 +1,62 @@
1
+ tz-lookup
2
+ =========
3
+
4
+ This is a little module that allows you to look up the current time zone of a
5
+ location, given it's latitude and longitude. I wrote it because the existing
6
+ Node module that does this (`tzwhere`) was far too slow to be useful in a
7
+ production setting. This module attempts to ameliorate that.
8
+
9
+ Usage
10
+ -----
11
+
12
+ To install:
13
+
14
+ npm install tz-lookup
15
+
16
+ To use:
17
+
18
+ > var tz = require("tz-lookup");
19
+ > console.log(tz(42.7235, -73.6931));
20
+ "America/New_York"
21
+
22
+ **Please take note of the following:**
23
+
24
+ * The exported function call will throw an error if the latitude or longitude
25
+ provided are NaN or out of bounds. Otherwise, it will never throw an error
26
+ and will always return an IANA timezone database string. (Barring bugs.)
27
+ * The exported function call is synchronous. Previous versions of this module
28
+ were asynchronous, due to the timezone database being too large to
29
+ conveniently fit in memory. Thanks to very careful data compression, this
30
+ is no longer the case.
31
+ * The timezones returned by this module are approximate: since the timezone
32
+ database is so large, lossy compression is necessary for fast lookups. In
33
+ particular, the compression used may be of insufficient resolution for
34
+ several very small timezones (such as Europe/Vatican) and favors country
35
+ timezones over GMT offsets (and so may exaggerate the distance of
36
+ territorial waters). However, the level of accuracy should be adequate for
37
+ most purposes. (For example, this module is used by the [Forecast API][1]
38
+ for global timezone lookups.)
39
+
40
+ If you find a real-world case where this module's accuracy is inadequate,
41
+ please open an issue (or, better yet, submit a pull request with a failing
42
+ test) and I'll see what I can do to increase the accuracy for you.
43
+
44
+ Sources
45
+ -------
46
+
47
+ Timezone data is from Eric Muller's excellent [TZ timezone maps][2]. To
48
+ regenerate the compressed database, simply download his `tz_world` shapefile,
49
+ convert it to a GeoJSON using GDAL, put it in the project directory (with the
50
+ name `tz_world.json`), and run `json2bin >tz.bin`. The timezone database was
51
+ last updated on 26 Nov 2013.
52
+
53
+ [1]: https://forecast.io/
54
+ [2]: http://efele.net/maps/tz/
55
+
56
+ License
57
+ -------
58
+
59
+ To the extend possible by law, The Dark Sky Company, LLC has [waived all
60
+ copyright and related or neighboring rights][cc0] to this library.
61
+
62
+ [cc0]: http://creativecommons.org/publicdomain/zero/1.0/
@@ -0,0 +1,169 @@
1
+ var DATA = require("fs").readFileSync(
2
+ require("path").join(__dirname, "tz.bin")
3
+ ),
4
+ TIMEZONE_LIST = [
5
+ "Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa", "Africa/Algiers",
6
+ "Africa/Asmara", "Africa/Bamako", "Africa/Bangui", "Africa/Banjul",
7
+ "Africa/Bissau", "Africa/Blantyre", "Africa/Brazzaville",
8
+ "Africa/Bujumbura", "Africa/Cairo", "Africa/Casablanca", "Africa/Ceuta",
9
+ "Africa/Conakry", "Africa/Dakar", "Africa/Dar_es_Salaam",
10
+ "Africa/Djibouti", "Africa/Douala", "Africa/El_Aaiun", "Africa/Freetown",
11
+ "Africa/Gaborone", "Africa/Harare", "Africa/Johannesburg", "Africa/Juba",
12
+ "Africa/Kampala", "Africa/Khartoum", "Africa/Kigali", "Africa/Kinshasa",
13
+ "Africa/Lagos", "Africa/Libreville", "Africa/Lome", "Africa/Luanda",
14
+ "Africa/Lubumbashi", "Africa/Lusaka", "Africa/Malabo", "Africa/Maputo",
15
+ "Africa/Maseru", "Africa/Mbabane", "Africa/Mogadishu", "Africa/Monrovia",
16
+ "Africa/Nairobi", "Africa/Ndjamena", "Africa/Niamey",
17
+ "Africa/Nouakchott", "Africa/Ouagadougou", "Africa/Porto-Novo",
18
+ "Africa/Sao_Tome", "Africa/Tripoli", "Africa/Tunis", "Africa/Windhoek",
19
+ "America/Adak", "America/Anchorage", "America/Anguilla",
20
+ "America/Antigua", "America/Araguaina", "America/Argentina/Buenos_Aires",
21
+ "America/Argentina/Catamarca", "America/Argentina/Cordoba",
22
+ "America/Argentina/Jujuy", "America/Argentina/La_Rioja",
23
+ "America/Argentina/Mendoza", "America/Argentina/Rio_Gallegos",
24
+ "America/Argentina/Salta", "America/Argentina/San_Juan",
25
+ "America/Argentina/San_Luis", "America/Argentina/Tucuman",
26
+ "America/Argentina/Ushuaia", "America/Aruba", "America/Asuncion",
27
+ "America/Atikokan", "America/Bahia", "America/Bahia_Banderas",
28
+ "America/Barbados", "America/Belem", "America/Belize",
29
+ "America/Blanc-Sablon", "America/Boa_Vista", "America/Bogota",
30
+ "America/Boise", "America/Cambridge_Bay", "America/Campo_Grande",
31
+ "America/Cancun", "America/Caracas", "America/Cayenne", "America/Cayman",
32
+ "America/Chicago", "America/Chihuahua", "America/Coral_Harbour",
33
+ "America/Costa_Rica", "America/Creston", "America/Cuiaba",
34
+ "America/Curacao", "America/Danmarkshavn", "America/Dawson",
35
+ "America/Dawson_Creek", "America/Denver", "America/Detroit",
36
+ "America/Dominica", "America/Edmonton", "America/Eirunepe",
37
+ "America/El_Salvador", "America/Fortaleza", "America/Glace_Bay",
38
+ "America/Godthab", "America/Goose_Bay", "America/Grand_Turk",
39
+ "America/Grenada", "America/Guadeloupe", "America/Guatemala",
40
+ "America/Guayaquil", "America/Guyana", "America/Halifax",
41
+ "America/Havana", "America/Hermosillo", "America/Indiana/Indianapolis",
42
+ "America/Indiana/Knox", "America/Indiana/Marengo",
43
+ "America/Indiana/Petersburg", "America/Indiana/Tell_City",
44
+ "America/Indiana/Vevay", "America/Indiana/Vincennes",
45
+ "America/Indiana/Winamac", "America/Inuvik", "America/Iqaluit",
46
+ "America/Jamaica", "America/Juneau", "America/Kentucky/Louisville",
47
+ "America/Kentucky/Monticello", "America/Kralendijk", "America/La_Paz",
48
+ "America/Lima", "America/Los_Angeles", "America/Lower_Princes",
49
+ "America/Maceio", "America/Managua", "America/Manaus", "America/Marigot",
50
+ "America/Martinique", "America/Matamoros", "America/Mazatlan",
51
+ "America/Menominee", "America/Merida", "America/Metlakatla",
52
+ "America/Mexico_City", "America/Miquelon", "America/Moncton",
53
+ "America/Monterrey", "America/Montevideo", "America/Montreal",
54
+ "America/Montserrat", "America/Nassau", "America/New_York",
55
+ "America/Nipigon", "America/Nome", "America/Noronha",
56
+ "America/North_Dakota/Beulah", "America/North_Dakota/Center",
57
+ "America/North_Dakota/New_Salem", "America/Ojinaga", "America/Panama",
58
+ "America/Pangnirtung", "America/Paramaribo", "America/Phoenix",
59
+ "America/Port-au-Prince", "America/Port_of_Spain", "America/Porto_Velho",
60
+ "America/Puerto_Rico", "America/Rainy_River", "America/Rankin_Inlet",
61
+ "America/Recife", "America/Regina", "America/Resolute",
62
+ "America/Rio_Branco", "America/Santa_Isabel", "America/Santarem",
63
+ "America/Santiago", "America/Santo_Domingo", "America/Sao_Paulo",
64
+ "America/Scoresbysund", "America/Sitka", "America/St_Barthelemy",
65
+ "America/St_Johns", "America/St_Kitts", "America/St_Lucia",
66
+ "America/St_Thomas", "America/St_Vincent", "America/Swift_Current",
67
+ "America/Tegucigalpa", "America/Thule", "America/Thunder_Bay",
68
+ "America/Tijuana", "America/Toronto", "America/Tortola",
69
+ "America/Vancouver", "America/Whitehorse", "America/Winnipeg",
70
+ "America/Yakutat", "America/Yellowknife", "Antarctica/Macquarie",
71
+ "Arctic/Longyearbyen", "Asia/Aden", "Asia/Almaty", "Asia/Amman",
72
+ "Asia/Anadyr", "Asia/Aqtau", "Asia/Aqtobe", "Asia/Ashgabat",
73
+ "Asia/Baghdad", "Asia/Bahrain", "Asia/Baku", "Asia/Bangkok",
74
+ "Asia/Beirut", "Asia/Bishkek", "Asia/Brunei", "Asia/Choibalsan",
75
+ "Asia/Chongqing", "Asia/Colombo", "Asia/Damascus", "Asia/Dhaka",
76
+ "Asia/Dili", "Asia/Dubai", "Asia/Dushanbe", "Asia/Gaza", "Asia/Harbin",
77
+ "Asia/Hebron", "Asia/Ho_Chi_Minh", "Asia/Hong_Kong", "Asia/Hovd",
78
+ "Asia/Irkutsk", "Asia/Jakarta", "Asia/Jayapura", "Asia/Jerusalem",
79
+ "Asia/Kabul", "Asia/Kamchatka", "Asia/Karachi", "Asia/Kashgar",
80
+ "Asia/Kathmandu", "Asia/Khandyga", "Asia/Kolkata", "Asia/Krasnoyarsk",
81
+ "Asia/Kuala_Lumpur", "Asia/Kuching", "Asia/Kuwait", "Asia/Macau",
82
+ "Asia/Magadan", "Asia/Makassar", "Asia/Manila", "Asia/Muscat",
83
+ "Asia/Nicosia", "Asia/Novokuznetsk", "Asia/Novosibirsk", "Asia/Omsk",
84
+ "Asia/Oral", "Asia/Phnom_Penh", "Asia/Pontianak", "Asia/Pyongyang",
85
+ "Asia/Qatar", "Asia/Qyzylorda", "Asia/Rangoon", "Asia/Riyadh",
86
+ "Asia/Sakhalin", "Asia/Samarkand", "Asia/Seoul", "Asia/Shanghai",
87
+ "Asia/Singapore", "Asia/Taipei", "Asia/Tashkent", "Asia/Tbilisi",
88
+ "Asia/Tehran", "Asia/Thimphu", "Asia/Tokyo", "Asia/Ulaanbaatar",
89
+ "Asia/Urumqi", "Asia/Ust-Nera", "Asia/Vientiane", "Asia/Vladivostok",
90
+ "Asia/Yakutsk", "Asia/Yekaterinburg", "Asia/Yerevan", "Atlantic/Azores",
91
+ "Atlantic/Bermuda", "Atlantic/Canary", "Atlantic/Cape_Verde",
92
+ "Atlantic/Faroe", "Atlantic/Madeira", "Atlantic/Reykjavik",
93
+ "Atlantic/South_Georgia", "Atlantic/St_Helena", "Atlantic/Stanley",
94
+ "Australia/Adelaide", "Australia/Brisbane", "Australia/Broken_Hill",
95
+ "Australia/Currie", "Australia/Darwin", "Australia/Eucla",
96
+ "Australia/Hobart", "Australia/Lindeman", "Australia/Lord_Howe",
97
+ "Australia/Melbourne", "Australia/Perth", "Australia/Sydney", "Etc/GMT",
98
+ "Etc/GMT+1", "Etc/GMT+10", "Etc/GMT+11", "Etc/GMT+12", "Etc/GMT+2",
99
+ "Etc/GMT+3", "Etc/GMT+4", "Etc/GMT+5", "Etc/GMT+6", "Etc/GMT+7",
100
+ "Etc/GMT+8", "Etc/GMT+9", "Etc/GMT-1", "Etc/GMT-10", "Etc/GMT-11",
101
+ "Etc/GMT-12", "Etc/GMT-2", "Etc/GMT-3", "Etc/GMT-4", "Etc/GMT-5",
102
+ "Etc/GMT-6", "Etc/GMT-7", "Etc/GMT-8", "Etc/GMT-9", "Europe/Amsterdam",
103
+ "Europe/Andorra", "Europe/Athens", "Europe/Belgrade", "Europe/Berlin",
104
+ "Europe/Bratislava", "Europe/Brussels", "Europe/Bucharest",
105
+ "Europe/Budapest", "Europe/Chisinau", "Europe/Copenhagen",
106
+ "Europe/Dublin", "Europe/Gibraltar", "Europe/Guernsey",
107
+ "Europe/Helsinki", "Europe/Isle_of_Man", "Europe/Istanbul",
108
+ "Europe/Jersey", "Europe/Kaliningrad", "Europe/Kiev", "Europe/Lisbon",
109
+ "Europe/Ljubljana", "Europe/London", "Europe/Luxembourg",
110
+ "Europe/Madrid", "Europe/Malta", "Europe/Mariehamn", "Europe/Minsk",
111
+ "Europe/Monaco", "Europe/Moscow", "Europe/Oslo", "Europe/Paris",
112
+ "Europe/Podgorica", "Europe/Prague", "Europe/Riga", "Europe/Rome",
113
+ "Europe/Samara", "Europe/San_Marino", "Europe/Sarajevo",
114
+ "Europe/Simferopol", "Europe/Skopje", "Europe/Sofia", "Europe/Stockholm",
115
+ "Europe/Tallinn", "Europe/Tirane", "Europe/Uzhgorod", "Europe/Vaduz",
116
+ "Europe/Vatican", "Europe/Vienna", "Europe/Vilnius", "Europe/Volgograd",
117
+ "Europe/Warsaw", "Europe/Zagreb", "Europe/Zaporozhye", "Europe/Zurich",
118
+ "Indian/Antananarivo", "Indian/Chagos", "Indian/Christmas",
119
+ "Indian/Cocos", "Indian/Comoro", "Indian/Kerguelen", "Indian/Mahe",
120
+ "Indian/Maldives", "Indian/Mauritius", "Indian/Mayotte",
121
+ "Indian/Reunion", "Pacific/Apia", "Pacific/Auckland", "Pacific/Chatham",
122
+ "Pacific/Chuuk", "Pacific/Easter", "Pacific/Efate", "Pacific/Enderbury",
123
+ "Pacific/Fakaofo", "Pacific/Fiji", "Pacific/Funafuti",
124
+ "Pacific/Galapagos", "Pacific/Gambier", "Pacific/Guadalcanal",
125
+ "Pacific/Guam", "Pacific/Honolulu", "Pacific/Johnston",
126
+ "Pacific/Kiritimati", "Pacific/Kosrae", "Pacific/Kwajalein",
127
+ "Pacific/Majuro", "Pacific/Marquesas", "Pacific/Midway", "Pacific/Nauru",
128
+ "Pacific/Niue", "Pacific/Norfolk", "Pacific/Noumea", "Pacific/Pago_Pago",
129
+ "Pacific/Palau", "Pacific/Pitcairn", "Pacific/Pohnpei",
130
+ "Pacific/Port_Moresby", "Pacific/Rarotonga", "Pacific/Saipan",
131
+ "Pacific/Tahiti", "Pacific/Tarawa", "Pacific/Tongatapu", "Pacific/Wake",
132
+ "Pacific/Wallis"
133
+ ],
134
+ COARSE_WIDTH = 48,
135
+ COARSE_HEIGHT = 24,
136
+ FINE_WIDTH = 2,
137
+ FINE_HEIGHT = 2,
138
+ MAX_TILES = 65536 - TIMEZONE_LIST.length;
139
+
140
+ module.exports = function(lat, lon) {
141
+ var x, u, y, v, t, i;
142
+
143
+ /* Make sure lat/lon are valid numbers. (It is unusual to check for the
144
+ * negation of whether the values are in range, but this form works for NaNs,
145
+ * too!) */
146
+ lat = +lat;
147
+ lon = +lon;
148
+ if(!(lat >= -90.0 && lat <= +90.0 && lon >= -180.0 && lon <= +180.0))
149
+ throw new RangeError("invalid coordinates");
150
+
151
+ /* The root node of the tree is wider than a normal node, acting essentially
152
+ * as a "flattened" few layers of the tree. This saves a bit of overhead,
153
+ * since the topmost nodes will probably all be full. */
154
+ u = (x = (180.0 + lon) * COARSE_WIDTH / 360.00000000000006)|0;
155
+ v = (y = ( 90.0 - lat) * COARSE_HEIGHT / 180.00000000000003)|0;
156
+ t = -1;
157
+ i = DATA.readUInt16BE((v * COARSE_WIDTH + u) << 1);
158
+
159
+ /* Recurse until we hit a leaf node. */
160
+ while(i < MAX_TILES) {
161
+ u = (x = ((x - u) % 1.0) * FINE_WIDTH )|0;
162
+ v = (y = ((y - v) % 1.0) * FINE_HEIGHT)|0;
163
+ t = t + i + 1;
164
+ i = DATA.readUInt16BE((COARSE_WIDTH * COARSE_HEIGHT + (t * FINE_HEIGHT + v) * FINE_WIDTH + u) << 1);
165
+ }
166
+
167
+ /* Once we hit a leaf, return the relevant timezone. */
168
+ return TIMEZONE_LIST[i - MAX_TILES];
169
+ };