moment-timezonejs-rails 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +4 -0
  4. data/lib/moment-timezonejs-rails.rb +10 -0
  5. data/lib/moment/timezonejs/rails/version.rb +7 -0
  6. data/test/dummy/Rakefile +7 -0
  7. data/test/dummy/config.ru +4 -0
  8. data/test/dummy/config/application.rb +64 -0
  9. data/test/dummy/config/boot.rb +10 -0
  10. data/test/dummy/config/environment.rb +5 -0
  11. data/test/dummy/config/environments/development.rb +31 -0
  12. data/test/dummy/config/environments/production.rb +64 -0
  13. data/test/dummy/config/environments/test.rb +35 -0
  14. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  15. data/test/dummy/config/initializers/inflections.rb +15 -0
  16. data/test/dummy/config/initializers/mime_types.rb +5 -0
  17. data/test/dummy/config/initializers/secret_token.rb +7 -0
  18. data/test/dummy/config/initializers/session_store.rb +8 -0
  19. data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
  20. data/test/dummy/config/locales/en.yml +5 -0
  21. data/test/dummy/config/routes.rb +2 -0
  22. data/test/dummy/log/test.log +19 -0
  23. data/test/dummy/tmp/cache/assets/C77/D70/sprockets%2F872b1621485a6656de327007baf54b14 +0 -0
  24. data/test/dummy/tmp/cache/assets/CF8/1C0/sprockets%2F0f8072dc4ae02f6433841f4031a3ec3b +0 -0
  25. data/test/dummy/tmp/cache/assets/DAE/E00/sprockets%2F27d4f79ef946a8265af7ce6bcb5cd602 +0 -0
  26. data/test/integration/navigation_test.rb +18 -0
  27. data/test/moment-timezonejs-rails_test.rb +7 -0
  28. data/test/test_helper.rb +15 -0
  29. data/vendor/assets/javascripts/moment-timezone-data/links.js +289 -0
  30. data/vendor/assets/javascripts/moment-timezone-data/meta.js +2214 -0
  31. data/vendor/assets/javascripts/moment-timezone-data/rules-since-2000.js +651 -0
  32. data/vendor/assets/javascripts/moment-timezone-data/rules.js +2234 -0
  33. data/vendor/assets/javascripts/moment-timezone-data/zones.js +2979 -0
  34. data/vendor/assets/javascripts/moment-timezone.js +540 -0
  35. metadata +141 -0
@@ -0,0 +1,540 @@
1
+ // moment-timezone.js
2
+ // version : 0.0.6
3
+ // author : Tim Wood
4
+ // license : MIT
5
+ // github.com/timrwood/moment-timezone
6
+
7
+ (function () {
8
+
9
+ var VERSION = "0.0.6";
10
+
11
+ function onload(moment) {
12
+ var oldZoneName = moment.fn.zoneName,
13
+ oldZoneAbbr = moment.fn.zoneAbbr,
14
+
15
+ defaultRule,
16
+ rules = {},
17
+ ruleSets = {},
18
+ zones = {},
19
+ zoneSets = {},
20
+ links = {},
21
+
22
+ TIME_RULE_WALL_CLOCK = 0,
23
+ TIME_RULE_UTC = 1,
24
+ TIME_RULE_STANDARD = 2,
25
+
26
+ DAY_RULE_DAY_OF_MONTH = 7,
27
+ DAY_RULE_LAST_WEEKDAY = 8;
28
+
29
+ if (moment.tz !== undefined) {
30
+ // Do not load moment-timezone a second time.
31
+ return moment;
32
+ }
33
+
34
+ // converts time in the HH:mm:ss format to absolute number of minutes
35
+ function parseMinutes (input) {
36
+ input = input + '';
37
+ var output = input.split(':'),
38
+ sign = ~input.indexOf('-') ? -1 : 1,
39
+ hour = Math.abs(+output[0]),
40
+ minute = parseInt(output[1], 10) || 0,
41
+ second = parseInt(output[2], 10) || 0;
42
+
43
+ return sign * ((hour * 60) + (minute) + (second / 60));
44
+ }
45
+
46
+ /************************************
47
+ Rules
48
+ ************************************/
49
+
50
+ function Rule (name, startYear, endYear, month, day, dayRule, time, timeRule, offset, letters) {
51
+ this.name = name;
52
+ this.startYear = +startYear;
53
+ this.endYear = +endYear;
54
+ this.month = +month;
55
+ this.day = +day;
56
+ this.dayRule = +dayRule;
57
+ this.time = parseMinutes(time);
58
+ this.timeRule = +timeRule;
59
+ this.offset = parseMinutes(offset);
60
+ this.letters = letters || '';
61
+ this.date = memoize(this.date);
62
+ this.weekdayAfter = memoize(this.weekdayAfter);
63
+ this.lastWeekday = memoize(this.lastWeekday);
64
+ }
65
+
66
+ Rule.prototype = {
67
+ contains : function (year) {
68
+ return (year >= this.startYear && year <= this.endYear);
69
+ },
70
+
71
+ start : function (year) {
72
+ year = Math.min(Math.max(year, this.startYear), this.endYear);
73
+ return moment.utc([year, this.month, this.date(year), 0, this.time]);
74
+ },
75
+
76
+ date : function (year) {
77
+ if (this.dayRule === DAY_RULE_DAY_OF_MONTH) {
78
+ return this.day;
79
+ } else if (this.dayRule === DAY_RULE_LAST_WEEKDAY) {
80
+ return this.lastWeekday(year);
81
+ }
82
+ return this.weekdayAfter(year);
83
+ },
84
+
85
+ weekdayAfter : function (year) {
86
+ var day = this.day,
87
+ firstDayOfWeek = moment([year, this.month, 1]).day(),
88
+ output = this.dayRule + 1 - firstDayOfWeek;
89
+
90
+ while (output < day) {
91
+ output += 7;
92
+ }
93
+
94
+ return output;
95
+ },
96
+
97
+ lastWeekday : function (year) {
98
+ var day = this.day,
99
+ dow = day % 7,
100
+ lastDowOfMonth = moment([year, this.month + 1, 1]).day(),
101
+ daysInMonth = moment([year, this.month, 1]).daysInMonth(),
102
+ output = daysInMonth + (dow - (lastDowOfMonth - 1)) - (~~(day / 7) * 7);
103
+
104
+ if (dow >= lastDowOfMonth) {
105
+ output -= 7;
106
+ }
107
+ return output;
108
+ }
109
+ };
110
+
111
+ /************************************
112
+ Rule Year
113
+ ************************************/
114
+
115
+ function RuleYear (year, rule) {
116
+ this.rule = rule;
117
+ this.start = rule.start(year);
118
+ }
119
+
120
+ RuleYear.prototype = {
121
+ equals : function (other) {
122
+ if (!other || other.rule !== this.rule) {
123
+ return false;
124
+ }
125
+ return Math.abs(other.start - this.start) < 86400000; // 24 * 60 * 60 * 1000
126
+ }
127
+ };
128
+
129
+ function sortRuleYears (a, b) {
130
+ if (a.isLast) {
131
+ return -1;
132
+ }
133
+ if (b.isLast) {
134
+ return 1;
135
+ }
136
+ return b.start - a.start;
137
+ }
138
+
139
+ /************************************
140
+ Rule Sets
141
+ ************************************/
142
+
143
+ function RuleSet (name) {
144
+ this.name = name;
145
+ this.rules = [];
146
+ this.lastYearRule = memoize(this.lastYearRule);
147
+ }
148
+
149
+ RuleSet.prototype = {
150
+ add : function (rule) {
151
+ this.rules.push(rule);
152
+ },
153
+
154
+ ruleYears : function (mom, lastZone) {
155
+ var i, j,
156
+ year = mom.year(),
157
+ rule,
158
+ lastZoneRule,
159
+ rules = [];
160
+
161
+ for (i = 0; i < this.rules.length; i++) {
162
+ rule = this.rules[i];
163
+ if (rule.contains(year)) {
164
+ rules.push(new RuleYear(year, rule));
165
+ } else if (rule.contains(year + 1)) {
166
+ rules.push(new RuleYear(year + 1, rule));
167
+ }
168
+ }
169
+ rules.push(new RuleYear(year - 1, this.lastYearRule(year - 1)));
170
+
171
+ if (lastZone) {
172
+ lastZoneRule = new RuleYear(year - 1, lastZone.lastRule());
173
+ lastZoneRule.start = lastZone.until.clone().utc();
174
+ lastZoneRule.isLast = lastZone.ruleSet !== this;
175
+ rules.push(lastZoneRule);
176
+ }
177
+
178
+ rules.sort(sortRuleYears);
179
+ return rules;
180
+ },
181
+
182
+ rule : function (mom, offset, lastZone) {
183
+ var rules = this.ruleYears(mom, lastZone),
184
+ lastOffset = 0,
185
+ rule,
186
+ lastZoneOffset,
187
+ lastZoneOffsetAbs,
188
+ lastRule,
189
+ i;
190
+
191
+ if (lastZone) {
192
+ lastZoneOffset = lastZone.offset + lastZone.lastRule().offset;
193
+ lastZoneOffsetAbs = Math.abs(lastZoneOffset) * 90000;
194
+ }
195
+
196
+ // make sure to include the previous rule's offset
197
+ for (i = rules.length - 1; i > -1; i--) {
198
+ lastRule = rule;
199
+ rule = rules[i];
200
+
201
+ if (rule.equals(lastRule)) {
202
+ continue;
203
+ }
204
+
205
+ if (lastZone && !rule.isLast && Math.abs(rule.start - lastZone.until) <= lastZoneOffsetAbs) {
206
+ lastOffset += lastZoneOffset - offset;
207
+ }
208
+
209
+ if (rule.rule.timeRule === TIME_RULE_STANDARD) {
210
+ lastOffset = offset;
211
+ }
212
+
213
+ if (rule.rule.timeRule !== TIME_RULE_UTC) {
214
+ rule.start.add('m', -lastOffset);
215
+ }
216
+
217
+ lastOffset = rule.rule.offset + offset;
218
+ }
219
+
220
+ for (i = 0; i < rules.length; i++) {
221
+ rule = rules[i];
222
+ if (mom >= rule.start && !rule.isLast) {
223
+ return rule.rule;
224
+ }
225
+ }
226
+
227
+ return defaultRule;
228
+ },
229
+
230
+ lastYearRule : function (year) {
231
+ var i,
232
+ rule,
233
+ start,
234
+ bestRule = defaultRule,
235
+ largest = -1e30;
236
+
237
+ for (i = 0; i < this.rules.length; i++) {
238
+ rule = this.rules[i];
239
+ if (year >= rule.startYear) {
240
+ start = rule.start(year);
241
+ if (start > largest) {
242
+ largest = start;
243
+ bestRule = rule;
244
+ }
245
+ }
246
+ }
247
+
248
+ return bestRule;
249
+ }
250
+ };
251
+
252
+ /************************************
253
+ Zone
254
+ ************************************/
255
+
256
+ function Zone (name, offset, ruleSet, letters, until, untilOffset) {
257
+ var i,
258
+ untilArray = typeof until === 'string' ? until.split('_') : [9999];
259
+
260
+ this.name = name;
261
+ this.offset = parseMinutes(offset);
262
+ this.ruleSet = ruleSet;
263
+ this.letters = letters;
264
+ this.lastRule = memoize(this.lastRule);
265
+
266
+ for (i = 0; i < untilArray.length; i++) {
267
+ untilArray[i] = +untilArray[i];
268
+ }
269
+ this.until = moment.utc(untilArray).subtract('m', parseMinutes(untilOffset));
270
+ }
271
+
272
+ Zone.prototype = {
273
+ rule : function (mom, lastZone) {
274
+ return this.ruleSet.rule(mom, this.offset, lastZone);
275
+ },
276
+
277
+ lastRule : function () {
278
+ return this.rule(this.until);
279
+ },
280
+
281
+ format : function (rule) {
282
+ return this.letters.replace("%s", rule.letters);
283
+ }
284
+ };
285
+
286
+ /************************************
287
+ Zone Set
288
+ ************************************/
289
+
290
+ function sortZones (a, b) {
291
+ return a.until - b.until;
292
+ }
293
+
294
+ function ZoneSet (name) {
295
+ this.name = normalizeName(name);
296
+ this.displayName = name;
297
+ this.zones = [];
298
+ this.zoneAndRule = memoize(this.zoneAndRule, function (mom) {
299
+ return +mom;
300
+ });
301
+ }
302
+
303
+ ZoneSet.prototype = {
304
+ zoneAndRule : function (mom) {
305
+ var i,
306
+ zone,
307
+ lastZone;
308
+
309
+ mom = mom.clone().utc();
310
+ for (i = 0; i < this.zones.length; i++) {
311
+ zone = this.zones[i];
312
+ if (mom < zone.until) {
313
+ break;
314
+ }
315
+ lastZone = zone;
316
+ }
317
+
318
+ return [zone, zone.rule(mom, lastZone)];
319
+ },
320
+
321
+ add : function (zone) {
322
+ this.zones.push(zone);
323
+ this.zones.sort(sortZones);
324
+ },
325
+
326
+ format : function (mom) {
327
+ var zoneAndRule = this.zoneAndRule(mom);
328
+ return zoneAndRule[0].format(zoneAndRule[1]);
329
+ },
330
+
331
+ offset : function (mom) {
332
+ var zoneAndRule = this.zoneAndRule(mom);
333
+ return -(zoneAndRule[0].offset + zoneAndRule[1].offset);
334
+ }
335
+ };
336
+
337
+ /************************************
338
+ Global Methods
339
+ ************************************/
340
+
341
+ function memoize (fn, keyFn) {
342
+ var cache = {};
343
+ return function (first) {
344
+ var key = keyFn ? keyFn.apply(this, arguments) : first;
345
+ return key in cache ?
346
+ cache[key] :
347
+ (cache[key] = fn.apply(this, arguments));
348
+ };
349
+ }
350
+
351
+ function addRules (rules) {
352
+ var i, j, rule;
353
+ for (i in rules) {
354
+ rule = rules[i];
355
+ for (j = 0; j < rule.length; j++) {
356
+ addRule(i + '\t' + rule[j]);
357
+ }
358
+ }
359
+ }
360
+
361
+ function addRule (ruleString) {
362
+ // don't duplicate rules
363
+ if (rules[ruleString]) {
364
+ return rules[ruleString];
365
+ }
366
+
367
+ var p = ruleString.split(/\s/),
368
+ name = normalizeName(p[0]),
369
+ rule = new Rule(name, p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10]);
370
+
371
+ // cache the rule so we don't add it again
372
+ rules[ruleString] = rule;
373
+
374
+ // add to the ruleset
375
+ getRuleSet(name).add(rule);
376
+
377
+ return rule;
378
+ }
379
+
380
+ function normalizeName (name) {
381
+ return (name || '').toLowerCase().replace(/\//g, '_');
382
+ }
383
+
384
+ function addZones (zones) {
385
+ var i, j, zone;
386
+ for (i in zones) {
387
+ zone = zones[i];
388
+ for (j = 0; j < zone.length; j++) {
389
+ addZone(i + '\t' + zone[j]);
390
+ }
391
+ }
392
+ }
393
+
394
+ function addLinks (linksToAdd) {
395
+ var i;
396
+ for (i in linksToAdd) {
397
+ links[normalizeName(i)] = normalizeName(linksToAdd[i]);
398
+ }
399
+ }
400
+
401
+ function addZone (zoneString) {
402
+ // don't duplicate zones
403
+ if (zones[zoneString]) {
404
+ return zones[zoneString];
405
+ }
406
+
407
+ var p = zoneString.split(/\s/),
408
+ name = normalizeName(p[0]),
409
+ zone = new Zone(name, p[1], getRuleSet(p[2]), p[3], p[4], p[5]);
410
+
411
+ // cache the zone so we don't add it again
412
+ zones[zoneString] = zone;
413
+
414
+ // add to the zoneset
415
+ getZoneSet(p[0]).add(zone);
416
+
417
+ return zone;
418
+ }
419
+
420
+ function getRuleSet (name) {
421
+ name = normalizeName(name);
422
+ if (!ruleSets[name]) {
423
+ ruleSets[name] = new RuleSet(name);
424
+ }
425
+ return ruleSets[name];
426
+ }
427
+
428
+ function getZoneSet (name) {
429
+ var machineName = normalizeName(name);
430
+ if (links[machineName]) {
431
+ machineName = links[machineName];
432
+ }
433
+ if (!zoneSets[machineName]) {
434
+ zoneSets[machineName] = new ZoneSet(name);
435
+ }
436
+ return zoneSets[machineName];
437
+ }
438
+
439
+ function add (data) {
440
+ if (!data) {
441
+ return;
442
+ }
443
+ if (data.zones) {
444
+ addZones(data.zones);
445
+ }
446
+ if (data.rules) {
447
+ addRules(data.rules);
448
+ }
449
+ if (data.links) {
450
+ addLinks(data.links);
451
+ }
452
+ }
453
+
454
+ // overwrite moment.updateOffset
455
+ moment.updateOffset = function (mom, keepTime) {
456
+ var offset;
457
+ if (mom._z) {
458
+ offset = mom._z.offset(mom);
459
+ if (Math.abs(offset) < 16) {
460
+ offset = offset / 60;
461
+ }
462
+ mom.zone(offset, keepTime);
463
+ }
464
+ };
465
+
466
+ function getZoneSets() {
467
+ var sets = [],
468
+ zoneName;
469
+ for (zoneName in zoneSets) {
470
+ sets.push(zoneSets[zoneName]);
471
+ }
472
+ return sets;
473
+ }
474
+
475
+ moment.fn.tz = function (name) {
476
+ if (name) {
477
+ this._z = getZoneSet(name);
478
+ if (this._z) {
479
+ moment.updateOffset(this);
480
+ }
481
+ return this;
482
+ }
483
+ if (this._z) {
484
+ return this._z.displayName;
485
+ }
486
+ };
487
+
488
+ moment.fn.zoneName = function () {
489
+ if (this._z) {
490
+ return this._z.format(this);
491
+ }
492
+ return oldZoneName.call(this);
493
+ };
494
+
495
+ moment.fn.zoneAbbr = function () {
496
+ if (this._z) {
497
+ return this._z.format(this);
498
+ }
499
+ return oldZoneAbbr.call(this);
500
+ };
501
+
502
+ // Make sure moment's clone includes the newly added properties
503
+ moment.momentProperties._z = null;
504
+
505
+ moment.tz = function () {
506
+ var args = [], i, len = arguments.length - 1;
507
+ for (i = 0; i < len; i++) {
508
+ args[i] = arguments[i];
509
+ }
510
+ var m = moment.apply(null, args);
511
+ var preTzOffset = m.zone();
512
+ m.tz(arguments[len]);
513
+ return m.add('minutes', m.zone() - preTzOffset);
514
+ };
515
+
516
+ moment.tz.add = add;
517
+ moment.tz.addRule = addRule;
518
+ moment.tz.addZone = addZone;
519
+ moment.tz.zones = getZoneSets;
520
+
521
+ moment.tz.version = VERSION;
522
+
523
+ moment.tz.zoneExists = function (name) {
524
+ return getZoneSet(name).zones.length > 0;
525
+ };
526
+
527
+ // add default rule
528
+ defaultRule = addRule("- 0 9999 0 0 0 0 0 0");
529
+
530
+ return moment;
531
+ }
532
+
533
+ if (typeof define === "function" && define.amd) {
534
+ define("moment-timezone", ["moment"], onload);
535
+ } else if (typeof module !== 'undefined') {
536
+ module.exports = onload(require('moment'));
537
+ } else if (typeof window !== "undefined" && window.moment) {
538
+ onload(window.moment);
539
+ }
540
+ }).apply(this);