moment-timezonejs-rails 0.0.6

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.
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);