browser_tzone 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/javascripts/browser_tzone/application.js +15 -0
  5. data/app/assets/javascripts/browser_tzone/detect_timezone.js +302 -0
  6. data/app/assets/javascripts/set_time_zone.js.coffee +2 -0
  7. data/app/assets/stylesheets/browser_tzone/application.css +13 -0
  8. data/app/controllers/browser_tzone/application_controller.rb +4 -0
  9. data/app/helpers/browser_tzone/application_helper.rb +4 -0
  10. data/app/views/layouts/browser_tzone/application.html.erb +14 -0
  11. data/config/routes.rb +2 -0
  12. data/lib/browser_tzone.rb +30 -0
  13. data/lib/browser_tzone/engine.rb +5 -0
  14. data/lib/browser_tzone/version.rb +3 -0
  15. data/lib/tasks/browser_tzone_tasks.rake +4 -0
  16. data/test/browser_tzone_test.rb +7 -0
  17. data/test/dummy/README.rdoc +261 -0
  18. data/test/dummy/Rakefile +7 -0
  19. data/test/dummy/app/assets/javascripts/application.js +15 -0
  20. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  21. data/test/dummy/app/controllers/application_controller.rb +3 -0
  22. data/test/dummy/app/helpers/application_helper.rb +2 -0
  23. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  24. data/test/dummy/config.ru +4 -0
  25. data/test/dummy/config/application.rb +59 -0
  26. data/test/dummy/config/boot.rb +10 -0
  27. data/test/dummy/config/database.yml +25 -0
  28. data/test/dummy/config/environment.rb +5 -0
  29. data/test/dummy/config/environments/development.rb +37 -0
  30. data/test/dummy/config/environments/production.rb +67 -0
  31. data/test/dummy/config/environments/test.rb +37 -0
  32. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  33. data/test/dummy/config/initializers/inflections.rb +15 -0
  34. data/test/dummy/config/initializers/mime_types.rb +5 -0
  35. data/test/dummy/config/initializers/secret_token.rb +7 -0
  36. data/test/dummy/config/initializers/session_store.rb +8 -0
  37. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  38. data/test/dummy/config/locales/en.yml +5 -0
  39. data/test/dummy/config/routes.rb +4 -0
  40. data/test/dummy/public/404.html +26 -0
  41. data/test/dummy/public/422.html +26 -0
  42. data/test/dummy/public/500.html +25 -0
  43. data/test/dummy/public/favicon.ico +0 -0
  44. data/test/dummy/script/rails +6 -0
  45. data/test/integration/navigation_test.rb +10 -0
  46. data/test/test_helper.rb +15 -0
  47. metadata +170 -0
@@ -0,0 +1,20 @@
1
+ Copyright 2013 YOURNAME
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.
@@ -0,0 +1,3 @@
1
+ = BrowserTzone
2
+
3
+ This project rocks and uses MIT-LICENSE.
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'BrowserTzone'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rake/testtask'
31
+
32
+ Rake::TestTask.new(:test) do |t|
33
+ t.libs << 'lib'
34
+ t.libs << 'test'
35
+ t.pattern = 'test/**/*_test.rb'
36
+ t.verbose = false
37
+ end
38
+
39
+
40
+ task :default => :test
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require_tree .
@@ -0,0 +1,302 @@
1
+ /*jslint undef: true */
2
+ /*global console*/
3
+ /*version 2012-05-10*/
4
+
5
+ /**
6
+ * Namespace to hold all the code for timezone detection.
7
+ */
8
+ var jstz = (function () {
9
+ 'use strict';
10
+ var HEMISPHERE_SOUTH = 's',
11
+
12
+ /**
13
+ * Gets the offset in minutes from UTC for a certain date.
14
+ * @param {Date} date
15
+ * @returns {Number}
16
+ */
17
+ get_date_offset = function (date) {
18
+ var offset = -date.getTimezoneOffset();
19
+ return (offset !== null ? offset : 0);
20
+ },
21
+
22
+ get_january_offset = function () {
23
+ return get_date_offset(new Date(2010, 0, 1, 0, 0, 0, 0));
24
+ },
25
+
26
+ get_june_offset = function () {
27
+ return get_date_offset(new Date(2010, 5, 1, 0, 0, 0, 0));
28
+ },
29
+
30
+ /**
31
+ * Private method.
32
+ * Checks whether a given date is in daylight savings time.
33
+ * If the date supplied is after june, we assume that we're checking
34
+ * for southern hemisphere DST.
35
+ * @param {Date} date
36
+ * @returns {Boolean}
37
+ */
38
+ date_is_dst = function (date) {
39
+ var base_offset = ((date.getMonth() > 5 ? get_june_offset()
40
+ : get_january_offset())),
41
+ date_offset = get_date_offset(date);
42
+
43
+ return (base_offset - date_offset) !== 0;
44
+ },
45
+
46
+ /**
47
+ * This function does some basic calculations to create information about
48
+ * the user's timezone.
49
+ *
50
+ * Returns a key that can be used to do lookups in jstz.olson.timezones.
51
+ *
52
+ * @returns {String}
53
+ */
54
+
55
+ lookup_key = function () {
56
+ var january_offset = get_january_offset(),
57
+ june_offset = get_june_offset(),
58
+ diff = get_january_offset() - get_june_offset();
59
+
60
+ if (diff < 0) {
61
+ return january_offset + ",1";
62
+ } else if (diff > 0) {
63
+ return june_offset + ",1," + HEMISPHERE_SOUTH;
64
+ }
65
+
66
+ return january_offset + ",0";
67
+ },
68
+
69
+ /**
70
+ * Uses get_timezone_info() to formulate a key to use in the olson.timezones dictionary.
71
+ *
72
+ * Returns a primitive object on the format:
73
+ * {'timezone': TimeZone, 'key' : 'the key used to find the TimeZone object'}
74
+ *
75
+ * @returns Object
76
+ */
77
+ determine = function () {
78
+ var key = lookup_key();
79
+ return new jstz.TimeZone(jstz.olson.timezones[key]);
80
+ };
81
+
82
+ return {
83
+ determine_timezone : function () {
84
+ if (typeof console !== 'undefined') {
85
+ console.log("jstz.determine_timezone() is deprecated and will be removed in an upcoming version. Please use jstz.determine() instead.");
86
+ }
87
+ return determine();
88
+ },
89
+ determine: determine,
90
+ date_is_dst : date_is_dst
91
+ };
92
+ }());
93
+
94
+ /**
95
+ * Simple object to perform ambiguity check and to return name of time zone.
96
+ */
97
+ jstz.TimeZone = function (tz_name) {
98
+ 'use strict';
99
+ var timezone_name = null,
100
+
101
+ name = function () {
102
+ return timezone_name;
103
+ },
104
+
105
+ /**
106
+ * Checks if a timezone has possible ambiguities. I.e timezones that are similar.
107
+ *
108
+ * For example, if the preliminary scan determines that we're in America/Denver.
109
+ * We double check here that we're really there and not in America/Mazatlan.
110
+ *
111
+ * This is done by checking known dates for when daylight savings start for different
112
+ * timezones during 2010 and 2011.
113
+ */
114
+ ambiguity_check = function () {
115
+ var ambiguity_list = jstz.olson.ambiguity_list[timezone_name],
116
+ length = ambiguity_list.length,
117
+ i = 0,
118
+ tz = ambiguity_list[0];
119
+
120
+ for (; i < length; i += 1) {
121
+ tz = ambiguity_list[i];
122
+
123
+ if (jstz.date_is_dst(jstz.olson.dst_start_dates[tz])) {
124
+ timezone_name = tz;
125
+ return;
126
+ }
127
+ }
128
+ },
129
+
130
+ /**
131
+ * Checks if it is possible that the timezone is ambiguous.
132
+ */
133
+ is_ambiguous = function () {
134
+ return typeof (jstz.olson.ambiguity_list[timezone_name]) !== 'undefined';
135
+ };
136
+
137
+
138
+
139
+ timezone_name = tz_name;
140
+ if (is_ambiguous()) {
141
+ ambiguity_check();
142
+ }
143
+
144
+ return {
145
+ name: name
146
+ };
147
+ };
148
+
149
+ jstz.olson = {};
150
+
151
+ /*
152
+ * The keys in this dictionary are comma separated as such:
153
+ *
154
+ * First the offset compared to UTC time in minutes.
155
+ *
156
+ * Then a flag which is 0 if the timezone does not take daylight savings into account and 1 if it
157
+ * does.
158
+ *
159
+ * Thirdly an optional 's' signifies that the timezone is in the southern hemisphere,
160
+ * only interesting for timezones with DST.
161
+ *
162
+ * The mapped arrays is used for constructing the jstz.TimeZone object from within
163
+ * jstz.determine_timezone();
164
+ */
165
+ jstz.olson.timezones = {
166
+ '-720,0' : 'Etc/GMT+12',
167
+ '-660,0' : 'Pacific/Pago_Pago',
168
+ '-600,1' : 'America/Adak',
169
+ '-600,0' : 'Pacific/Honolulu',
170
+ '-570,0' : 'Pacific/Marquesas',
171
+ '-540,0' : 'Pacific/Gambier',
172
+ '-540,1' : 'America/Anchorage',
173
+ '-480,1' : 'America/Los_Angeles',
174
+ '-480,0' : 'Pacific/Pitcairn',
175
+ '-420,0' : 'America/Phoenix',
176
+ '-420,1' : 'America/Denver',
177
+ '-360,0' : 'America/Guatemala',
178
+ '-360,1' : 'America/Chicago',
179
+ '-360,1,s' : 'Pacific/Easter',
180
+ '-300,0' : 'America/Bogota',
181
+ '-300,1' : 'America/New_York',
182
+ '-270,0' : 'America/Caracas',
183
+ '-240,1' : 'America/Halifax',
184
+ '-240,0' : 'America/Santo_Domingo',
185
+ '-240,1,s' : 'America/Asuncion',
186
+ '-210,1' : 'America/St_Johns',
187
+ '-180,1' : 'America/Godthab',
188
+ '-180,0' : 'America/Argentina/Buenos_Aires',
189
+ '-180,1,s' : 'America/Montevideo',
190
+ '-120,0' : 'America/Noronha',
191
+ '-120,1' : 'Etc/GMT+2',
192
+ '-60,1' : 'Atlantic/Azores',
193
+ '-60,0' : 'Atlantic/Cape_Verde',
194
+ '0,0' : 'Etc/UTC',
195
+ '0,1' : 'Europe/London',
196
+ '60,1' : 'Europe/Berlin',
197
+ '60,0' : 'Africa/Lagos',
198
+ '60,1,s' : 'Africa/Windhoek',
199
+ '120,1' : 'Asia/Beirut',
200
+ '120,0' : 'Africa/Johannesburg',
201
+ '180,1' : 'Europe/Moscow',
202
+ '180,0' : 'Asia/Baghdad',
203
+ '210,1' : 'Asia/Tehran',
204
+ '240,0' : 'Asia/Dubai',
205
+ '240,1' : 'Asia/Yerevan',
206
+ '270,0' : 'Asia/Kabul',
207
+ '300,1' : 'Asia/Yekaterinburg',
208
+ '300,0' : 'Asia/Karachi',
209
+ '330,0' : 'Asia/Kolkata',
210
+ '345,0' : 'Asia/Kathmandu',
211
+ '360,0' : 'Asia/Dhaka',
212
+ '360,1' : 'Asia/Omsk',
213
+ '390,0' : 'Asia/Rangoon',
214
+ '420,1' : 'Asia/Krasnoyarsk',
215
+ '420,0' : 'Asia/Jakarta',
216
+ '480,0' : 'Asia/Shanghai',
217
+ '480,1' : 'Asia/Irkutsk',
218
+ '525,0' : 'Australia/Eucla',
219
+ '525,1,s' : 'Australia/Eucla',
220
+ '540,1' : 'Asia/Yakutsk',
221
+ '540,0' : 'Asia/Tokyo',
222
+ '570,0' : 'Australia/Darwin',
223
+ '570,1,s' : 'Australia/Adelaide',
224
+ '600,0' : 'Australia/Brisbane',
225
+ '600,1' : 'Asia/Vladivostok',
226
+ '600,1,s' : 'Australia/Sydney',
227
+ '630,1,s' : 'Australia/Lord_Howe',
228
+ '660,1' : 'Asia/Kamchatka',
229
+ '660,0' : 'Pacific/Noumea',
230
+ '690,0' : 'Pacific/Norfolk',
231
+ '720,1,s' : 'Pacific/Auckland',
232
+ '720,0' : 'Pacific/Tarawa',
233
+ '765,1,s' : 'Pacific/Chatham',
234
+ '780,0' : 'Pacific/Tongatapu',
235
+ '780,1,s' : 'Pacific/Apia',
236
+ '840,0' : 'Pacific/Kiritimati'
237
+ };
238
+
239
+
240
+ /**
241
+ * This object contains information on when daylight savings starts for
242
+ * different timezones.
243
+ *
244
+ * The list is short for a reason. Often we do not have to be very specific
245
+ * to single out the correct timezone. But when we do, this list comes in
246
+ * handy.
247
+ *
248
+ * Each value is a date denoting when daylight savings starts for that timezone.
249
+ */
250
+ jstz.olson.dst_start_dates = {
251
+ 'America/Denver' : new Date(2011, 2, 13, 3, 0, 0, 0),
252
+ 'America/Mazatlan' : new Date(2011, 3, 3, 3, 0, 0, 0),
253
+ 'America/Chicago' : new Date(2011, 2, 13, 3, 0, 0, 0),
254
+ 'America/Mexico_City' : new Date(2011, 3, 3, 3, 0, 0, 0),
255
+ 'Atlantic/Stanley' : new Date(2011, 8, 4, 7, 0, 0, 0),
256
+ 'America/Asuncion' : new Date(2011, 9, 2, 3, 0, 0, 0),
257
+ 'America/Santiago' : new Date(2011, 9, 9, 3, 0, 0, 0),
258
+ 'America/Campo_Grande' : new Date(2011, 9, 16, 5, 0, 0, 0),
259
+ 'America/Montevideo' : new Date(2011, 9, 2, 3, 0, 0, 0),
260
+ 'America/Sao_Paulo' : new Date(2011, 9, 16, 5, 0, 0, 0),
261
+ 'America/Los_Angeles' : new Date(2011, 2, 13, 8, 0, 0, 0),
262
+ 'America/Santa_Isabel' : new Date(2011, 3, 5, 8, 0, 0, 0),
263
+ 'America/Havana' : new Date(2011, 2, 13, 2, 0, 0, 0),
264
+ 'America/New_York' : new Date(2011, 2, 13, 7, 0, 0, 0),
265
+ 'Asia/Gaza' : new Date(2011, 2, 26, 23, 0, 0, 0),
266
+ 'Asia/Beirut' : new Date(2011, 2, 27, 1, 0, 0, 0),
267
+ 'Europe/Minsk' : new Date(2011, 2, 27, 2, 0, 0, 0),
268
+ 'Europe/Helsinki' : new Date(2011, 2, 27, 4, 0, 0, 0),
269
+ 'Europe/Istanbul' : new Date(2011, 2, 28, 5, 0, 0, 0),
270
+ 'Asia/Damascus' : new Date(2011, 3, 1, 2, 0, 0, 0),
271
+ 'Asia/Jerusalem' : new Date(2011, 3, 1, 6, 0, 0, 0),
272
+ 'Africa/Cairo' : new Date(2010, 3, 30, 4, 0, 0, 0),
273
+ 'Asia/Yerevan' : new Date(2011, 2, 27, 4, 0, 0, 0),
274
+ 'Asia/Baku' : new Date(2011, 2, 27, 8, 0, 0, 0),
275
+ 'Pacific/Auckland' : new Date(2011, 8, 26, 7, 0, 0, 0),
276
+ 'Pacific/Fiji' : new Date(2010, 11, 29, 23, 0, 0, 0),
277
+ 'America/Halifax' : new Date(2011, 2, 13, 6, 0, 0, 0),
278
+ 'America/Goose_Bay' : new Date(2011, 2, 13, 2, 1, 0, 0),
279
+ 'America/Miquelon' : new Date(2011, 2, 13, 5, 0, 0, 0),
280
+ 'America/Godthab' : new Date(2011, 2, 27, 1, 0, 0, 0)
281
+ };
282
+
283
+ /**
284
+ * The keys in this object are timezones that we know may be ambiguous after
285
+ * a preliminary scan through the olson_tz object.
286
+ *
287
+ * The array of timezones to compare must be in the order that daylight savings
288
+ * starts for the regions.
289
+ */
290
+ jstz.olson.ambiguity_list = {
291
+ 'America/Denver' : ['America/Denver', 'America/Mazatlan'],
292
+ 'America/Chicago' : ['America/Chicago', 'America/Mexico_City'],
293
+ 'America/Asuncion' : ['Atlantic/Stanley', 'America/Asuncion', 'America/Santiago', 'America/Campo_Grande'],
294
+ 'America/Montevideo' : ['America/Montevideo', 'America/Sao_Paulo'],
295
+ 'Asia/Beirut' : ['Asia/Gaza', 'Asia/Beirut', 'Europe/Minsk', 'Europe/Helsinki', 'Europe/Istanbul', 'Asia/Damascus', 'Asia/Jerusalem', 'Africa/Cairo'],
296
+ 'Asia/Yerevan' : ['Asia/Yerevan', 'Asia/Baku'],
297
+ 'Pacific/Auckland' : ['Pacific/Auckland', 'Pacific/Fiji'],
298
+ 'America/Los_Angeles' : ['America/Los_Angeles', 'America/Santa_Isabel'],
299
+ 'America/New_York' : ['America/Havana', 'America/New_York'],
300
+ 'America/Halifax' : ['America/Goose_Bay', 'America/Halifax'],
301
+ 'America/Godthab' : ['America/Miquelon', 'America/Godthab']
302
+ };
@@ -0,0 +1,2 @@
1
+ jQuery ->
2
+ $.cookie "browser.timezone", jstz.determine().name()
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,4 @@
1
+ module BrowserTzone
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module BrowserTzone
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>BrowserTzone</title>
5
+ <%= stylesheet_link_tag "browser_tzone/application", :media => "all" %>
6
+ <%= javascript_include_tag "browser_tzone/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,2 @@
1
+ BrowserTzone::Engine.routes.draw do
2
+ end
@@ -0,0 +1,30 @@
1
+ require "browser_tzone/engine"
2
+
3
+ module BrowserTzone
4
+ class Railtie < Rails::Railtie
5
+ initializer 'browser_tzone.initialize' do |app|
6
+
7
+ ::ApplicationController.class_eval do
8
+
9
+ around_filter :set_time_zone
10
+
11
+ private
12
+
13
+ def set_time_zone
14
+ old_time_zone = Time.zone
15
+ Time.zone = browser_timezone if browser_timezone.present?
16
+ yield
17
+ ensure
18
+ Time.zone = old_time_zone
19
+ end
20
+
21
+ def browser_timezone
22
+ cookies["browser.timezone"].tap{ |tz| logger.debug "detected timezone #{tz}" }
23
+ end
24
+
25
+
26
+ end
27
+
28
+ end
29
+ end
30
+ end