mobiscroll-rails 2.3.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,656 @@
1
+ /*jslint eqeq: true, plusplus: true, undef: true, sloppy: true, vars: true, forin: true */
2
+ (function ($) {
3
+
4
+ var ms = $.mobiscroll,
5
+ date = new Date(),
6
+ defaults = {
7
+ dateFormat: 'mm/dd/yy',
8
+ dateOrder: 'mmddy',
9
+ timeWheels: 'hhiiA',
10
+ timeFormat: 'hh:ii A',
11
+ startYear: date.getFullYear() - 100,
12
+ endYear: date.getFullYear() + 1,
13
+ monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
14
+ monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
15
+ dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
16
+ dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
17
+ shortYearCutoff: '+10',
18
+ monthText: 'Month',
19
+ dayText: 'Day',
20
+ yearText: 'Year',
21
+ hourText: 'Hours',
22
+ minuteText: 'Minutes',
23
+ secText: 'Seconds',
24
+ ampmText: ' ',
25
+ nowText: 'Now',
26
+ showNow: false,
27
+ stepHour: 1,
28
+ stepMinute: 1,
29
+ stepSecond: 1,
30
+ separator: ' '
31
+ },
32
+ preset = function (inst) {
33
+ var that = $(this),
34
+ html5def = {},
35
+ format;
36
+ // Force format for html5 date inputs (experimental)
37
+ if (that.is('input')) {
38
+ switch (that.attr('type')) {
39
+ case 'date':
40
+ format = 'yy-mm-dd';
41
+ break;
42
+ case 'datetime':
43
+ format = 'yy-mm-ddTHH:ii:ssZ';
44
+ break;
45
+ case 'datetime-local':
46
+ format = 'yy-mm-ddTHH:ii:ss';
47
+ break;
48
+ case 'month':
49
+ format = 'yy-mm';
50
+ html5def.dateOrder = 'mmyy';
51
+ break;
52
+ case 'time':
53
+ format = 'HH:ii:ss';
54
+ break;
55
+ }
56
+ // Check for min/max attributes
57
+ var min = that.attr('min'),
58
+ max = that.attr('max');
59
+ if (min) {
60
+ html5def.minDate = ms.parseDate(format, min);
61
+ }
62
+ if (max) {
63
+ html5def.maxDate = ms.parseDate(format, max);
64
+ }
65
+ }
66
+
67
+ // Set year-month-day order
68
+ var s = $.extend({}, defaults, html5def, inst.settings),
69
+ offset = 0,
70
+ wheels = [],
71
+ ord = [],
72
+ o = {},
73
+ i,
74
+ k,
75
+ f = { y: 'getFullYear', m: 'getMonth', d: 'getDate', h: getHour, i: getMinute, s: getSecond, ap: getAmPm },
76
+ p = s.preset,
77
+ dord = s.dateOrder,
78
+ tord = s.timeWheels,
79
+ regen = dord.match(/D/),
80
+ ampm = tord.match(/a/i),
81
+ hampm = tord.match(/h/),
82
+ hformat = p == 'datetime' ? s.dateFormat + s.separator + s.timeFormat : p == 'time' ? s.timeFormat : s.dateFormat,
83
+ defd = new Date(),
84
+ stepH = s.stepHour,
85
+ stepM = s.stepMinute,
86
+ stepS = s.stepSecond,
87
+ mind = s.minDate || new Date(s.startYear, 0, 1),
88
+ maxd = s.maxDate || new Date(s.endYear, 11, 31, 23, 59, 59);
89
+
90
+ format = format || hformat;
91
+
92
+ if (p.match(/date/i)) {
93
+
94
+ // Determine the order of year, month, day wheels
95
+ $.each(['y', 'm', 'd'], function (j, v) {
96
+ i = dord.search(new RegExp(v, 'i'));
97
+ if (i > -1) {
98
+ ord.push({ o: i, v: v });
99
+ }
100
+ });
101
+ ord.sort(function (a, b) { return a.o > b.o ? 1 : -1; });
102
+ $.each(ord, function (i, v) {
103
+ o[v.v] = i;
104
+ });
105
+
106
+ var w = {};
107
+ for (k = 0; k < 3; k++) {
108
+ if (k == o.y) {
109
+ offset++;
110
+ w[s.yearText] = {};
111
+ var start = mind.getFullYear(),
112
+ end = maxd.getFullYear();
113
+ for (i = start; i <= end; i++) {
114
+ w[s.yearText][i] = dord.match(/yy/i) ? i : (i + '').substr(2, 2);
115
+ }
116
+ } else if (k == o.m) {
117
+ offset++;
118
+ w[s.monthText] = {};
119
+ for (i = 0; i < 12; i++) {
120
+ var str = dord.replace(/[dy]/gi, '').replace(/mm/, i < 9 ? '0' + (i + 1) : i + 1).replace(/m/, i);
121
+ w[s.monthText][i] = str.match(/MM/) ? str.replace(/MM/, '<span class="dw-mon">' + s.monthNames[i] + '</span>') : str.replace(/M/, '<span class="dw-mon">' + s.monthNamesShort[i] + '</span>');
122
+ }
123
+ } else if (k == o.d) {
124
+ offset++;
125
+ w[s.dayText] = {};
126
+ for (i = 1; i < 32; i++) {
127
+ w[s.dayText][i] = dord.match(/dd/i) && i < 10 ? '0' + i : i;
128
+ }
129
+ }
130
+ }
131
+ wheels.push(w);
132
+ }
133
+
134
+ if (p.match(/time/i)) {
135
+
136
+ // Determine the order of hours, minutes, seconds wheels
137
+ ord = [];
138
+ $.each(['h', 'i', 's'], function (i, v) {
139
+ i = tord.search(new RegExp(v, 'i'));
140
+ if (i > -1) {
141
+ ord.push({ o: i, v: v });
142
+ }
143
+ });
144
+ ord.sort(function (a, b) {
145
+ return a.o > b.o ? 1 : -1;
146
+ });
147
+ $.each(ord, function (i, v) {
148
+ o[v.v] = offset + i;
149
+ });
150
+
151
+ w = {};
152
+ for (k = offset; k < offset + 3; k++) {
153
+ if (k == o.h) {
154
+ offset++;
155
+ w[s.hourText] = {};
156
+ for (i = 0; i < (hampm ? 12 : 24); i += stepH) {
157
+ w[s.hourText][i] = hampm && i == 0 ? 12 : tord.match(/hh/i) && i < 10 ? '0' + i : i;
158
+ }
159
+ } else if (k == o.i) {
160
+ offset++;
161
+ w[s.minuteText] = {};
162
+ for (i = 0; i < 60; i += stepM) {
163
+ w[s.minuteText][i] = tord.match(/ii/) && i < 10 ? '0' + i : i;
164
+ }
165
+ } else if (k == o.s) {
166
+ offset++;
167
+ w[s.secText] = {};
168
+ for (i = 0; i < 60; i += stepS) {
169
+ w[s.secText][i] = tord.match(/ss/) && i < 10 ? '0' + i : i;
170
+ }
171
+ }
172
+ }
173
+
174
+ if (ampm) {
175
+ o.ap = offset++; // ampm wheel order
176
+ var upper = tord.match(/A/);
177
+ w[s.ampmText] = { 0: upper ? 'AM' : 'am', 1: upper ? 'PM' : 'pm' };
178
+ }
179
+ wheels.push(w);
180
+ }
181
+
182
+ function get(d, i, def) {
183
+ if (o[i] !== undefined) {
184
+ return +d[o[i]];
185
+ }
186
+ if (def !== undefined) {
187
+ return def;
188
+ }
189
+ return defd[f[i]] ? defd[f[i]]() : f[i](defd);
190
+ }
191
+
192
+ function step(v, st) {
193
+ return Math.floor(v / st) * st;
194
+ }
195
+
196
+ function getHour(d) {
197
+ var hour = d.getHours();
198
+ hour = hampm && hour >= 12 ? hour - 12 : hour;
199
+ return step(hour, stepH);
200
+ }
201
+
202
+ function getMinute(d) {
203
+ return step(d.getMinutes(), stepM);
204
+ }
205
+
206
+ function getSecond(d) {
207
+ return step(d.getSeconds(), stepS);
208
+ }
209
+
210
+ function getAmPm(d) {
211
+ return ampm && d.getHours() > 11 ? 1 : 0;
212
+ }
213
+
214
+ function getDate(d) {
215
+ var hour = get(d, 'h', 0);
216
+ return new Date(get(d, 'y'), get(d, 'm'), get(d, 'd', 1), get(d, 'ap') ? hour + 12 : hour, get(d, 'i', 0), get(d, 's', 0));
217
+ }
218
+
219
+ inst.setDate = function (d, fill, time, temp) {
220
+ var i;
221
+ // Set wheels
222
+ for (i in o) {
223
+ this.temp[o[i]] = d[f[i]] ? d[f[i]]() : f[i](d);
224
+ }
225
+ this.setValue(true, fill, time, temp);
226
+ };
227
+
228
+ inst.getDate = function (d) {
229
+ return getDate(d);
230
+ };
231
+
232
+ return {
233
+ button3Text: s.showNow ? s.nowText : undefined,
234
+ button3: s.showNow ? function () { inst.setDate(new Date(), false, 0.3, true); } : undefined,
235
+ wheels: wheels,
236
+ headerText: function (v) {
237
+ return ms.formatDate(hformat, getDate(inst.temp), s);
238
+ },
239
+ /**
240
+ * Builds a date object from the wheel selections and formats it to the given date/time format
241
+ * @param {Array} d - An array containing the selected wheel values
242
+ * @return {String} - The formatted date string
243
+ */
244
+ formatResult: function (d) {
245
+ return ms.formatDate(format, getDate(d), s);
246
+ },
247
+ /**
248
+ * Builds a date object from the input value and returns an array to set wheel values
249
+ * @return {Array} - An array containing the wheel values to set
250
+ */
251
+ parseValue: function (val) {
252
+ var d = new Date(),
253
+ i,
254
+ result = [];
255
+ try {
256
+ d = ms.parseDate(format, val, s);
257
+ } catch (e) {
258
+ }
259
+ // Set wheels
260
+ for (i in o) {
261
+ result[o[i]] = d[f[i]] ? d[f[i]]() : f[i](d);
262
+ }
263
+ return result;
264
+ },
265
+ /**
266
+ * Validates the selected date to be in the minDate / maxDate range and sets unselectable values to disabled
267
+ * @param {Object} dw - jQuery object containing the generated html
268
+ * @param {Integer} [i] - Index of the changed wheel, not set for initial validation
269
+ */
270
+ validate: function (dw, i) {
271
+ var temp = inst.temp, //.slice(0),
272
+ mins = { y: mind.getFullYear(), m: 0, d: 1, h: 0, i: 0, s: 0, ap: 0 },
273
+ maxs = { y: maxd.getFullYear(), m: 11, d: 31, h: step(hampm ? 11 : 23, stepH), i: step(59, stepM), s: step(59, stepS), ap: 1 },
274
+ minprop = true,
275
+ maxprop = true;
276
+ $.each(['y', 'm', 'd', 'ap', 'h', 'i', 's'], function (x, i) {
277
+ if (o[i] !== undefined) {
278
+ var min = mins[i],
279
+ max = maxs[i],
280
+ maxdays = 31,
281
+ val = get(temp, i),
282
+ t = $('ul', dw).eq(o[i]),
283
+ y,
284
+ m;
285
+ if (i == 'd') {
286
+ y = get(temp, 'y');
287
+ m = get(temp, 'm');
288
+ maxdays = 32 - new Date(y, m, 32).getDate();
289
+ max = maxdays;
290
+ if (regen) {
291
+ $('li', t).each(function () {
292
+ var that = $(this),
293
+ d = that.data('val'),
294
+ w = new Date(y, m, d).getDay(),
295
+ str = dord.replace(/[my]/gi, '').replace(/dd/, d < 10 ? '0' + d : d).replace(/d/, d);
296
+ $('.dw-i', that).html(str.match(/DD/) ? str.replace(/DD/, '<span class="dw-day">' + s.dayNames[w] + '</span>') : str.replace(/D/, '<span class="dw-day">' + s.dayNamesShort[w] + '</span>'));
297
+ });
298
+ }
299
+ }
300
+ if (minprop && mind) {
301
+ min = mind[f[i]] ? mind[f[i]]() : f[i](mind);
302
+ }
303
+ if (maxprop && maxd) {
304
+ max = maxd[f[i]] ? maxd[f[i]]() : f[i](maxd);
305
+ }
306
+ if (i != 'y') {
307
+ var i1 = $('li[data-val="' + min + '"]', t).index(),
308
+ i2 = $('li[data-val="' + max + '"]', t).index();
309
+ $('li', t).removeClass('dw-v').slice(i1, i2 + 1).addClass('dw-v');
310
+ if (i == 'd') { // Hide days not in month
311
+ $('li', t).removeClass('dw-h').slice(maxdays).addClass('dw-h');
312
+ }
313
+ }
314
+ if (val < min) {
315
+ val = min;
316
+ }
317
+ if (val > max) {
318
+ val = max;
319
+ }
320
+ if (minprop) {
321
+ minprop = val == min;
322
+ }
323
+ if (maxprop) {
324
+ maxprop = val == max;
325
+ }
326
+ // Disable some days
327
+ if (s.invalid && i == 'd') {
328
+ var idx = [];
329
+ // Disable exact dates
330
+ if (s.invalid.dates) {
331
+ $.each(s.invalid.dates, function (i, v) {
332
+ if (v.getFullYear() == y && v.getMonth() == m) {
333
+ idx.push(v.getDate() - 1);
334
+ }
335
+ });
336
+ }
337
+ // Disable days of week
338
+ if (s.invalid.daysOfWeek) {
339
+ var first = new Date(y, m, 1).getDay(),
340
+ j;
341
+ $.each(s.invalid.daysOfWeek, function (i, v) {
342
+ for (j = v - first; j < maxdays; j += 7) {
343
+ if (j >= 0) {
344
+ idx.push(j);
345
+ }
346
+ }
347
+ });
348
+ }
349
+ // Disable days of month
350
+ if (s.invalid.daysOfMonth) {
351
+ $.each(s.invalid.daysOfMonth, function (i, v) {
352
+ v = (v + '').split('/');
353
+ if (v[1]) {
354
+ if (v[0] - 1 == m) {
355
+ idx.push(v[1] - 1);
356
+ }
357
+ } else {
358
+ idx.push(v[0] - 1);
359
+ }
360
+ });
361
+ }
362
+ $.each(idx, function (i, v) {
363
+ $('li', t).eq(v).removeClass('dw-v');
364
+ });
365
+ }
366
+
367
+ // Set modified value
368
+ temp[o[i]] = val;
369
+ }
370
+ });
371
+ },
372
+ methods: {
373
+ /**
374
+ * Returns the currently selected date.
375
+ * @param {Boolean} temp - If true, return the currently shown date on the picker, otherwise the last selected one
376
+ * @return {Date}
377
+ */
378
+ getDate: function (temp) {
379
+ var inst = $(this).mobiscroll('getInst');
380
+ if (inst) {
381
+ return inst.getDate(temp ? inst.temp : inst.values);
382
+ }
383
+ },
384
+ /**
385
+ * Sets the selected date
386
+ * @param {Date} d - Date to select.
387
+ * @param {Boolean} [fill] - Also set the value of the associated input element. Default is true.
388
+ * @return {Object} - jQuery object to maintain chainability
389
+ */
390
+ setDate: function (d, fill, time, temp) {
391
+ if (fill == undefined) {
392
+ fill = false;
393
+ }
394
+ return this.each(function () {
395
+ var inst = $(this).mobiscroll('getInst');
396
+ if (inst) {
397
+ inst.setDate(d, fill, time, temp);
398
+ }
399
+ });
400
+ }
401
+ }
402
+ };
403
+ };
404
+
405
+ $.each(['date', 'time', 'datetime'], function(i, v) {
406
+ ms.presets[v] = preset;
407
+ ms.presetShort(v);
408
+ });
409
+
410
+ /**
411
+ * Format a date into a string value with a specified format.
412
+ * @param {String} format - Output format.
413
+ * @param {Date} date - Date to format.
414
+ * @param {Object} settings - Settings.
415
+ * @return {String} - Returns the formatted date string.
416
+ */
417
+ ms.formatDate = function (format, date, settings) {
418
+ if (!date) {
419
+ return null;
420
+ }
421
+ var s = $.extend({}, defaults, settings),
422
+ look = function (m) { // Check whether a format character is doubled
423
+ var n = 0;
424
+ while (i + 1 < format.length && format.charAt(i + 1) == m) {
425
+ n++;
426
+ i++;
427
+ }
428
+ return n;
429
+ },
430
+ f1 = function (m, val, len) { // Format a number, with leading zero if necessary
431
+ var n = '' + val;
432
+ if (look(m)) {
433
+ while (n.length < len) {
434
+ n = '0' + n;
435
+ }
436
+ }
437
+ return n;
438
+ },
439
+ f2 = function (m, val, s, l) { // Format a name, short or long as requested
440
+ return (look(m) ? l[val] : s[val]);
441
+ },
442
+ i,
443
+ output = '',
444
+ literal = false;
445
+
446
+ for (i = 0; i < format.length; i++) {
447
+ if (literal) {
448
+ if (format.charAt(i) == "'" && !look("'")) {
449
+ literal = false;
450
+ } else {
451
+ output += format.charAt(i);
452
+ }
453
+ } else {
454
+ switch (format.charAt(i)) {
455
+ case 'd':
456
+ output += f1('d', date.getDate(), 2);
457
+ break;
458
+ case 'D':
459
+ output += f2('D', date.getDay(), s.dayNamesShort, s.dayNames);
460
+ break;
461
+ case 'o':
462
+ output += f1('o', (date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3);
463
+ break;
464
+ case 'm':
465
+ output += f1('m', date.getMonth() + 1, 2);
466
+ break;
467
+ case 'M':
468
+ output += f2('M', date.getMonth(), s.monthNamesShort, s.monthNames);
469
+ break;
470
+ case 'y':
471
+ output += (look('y') ? date.getFullYear() : (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
472
+ break;
473
+ case 'h':
474
+ var h = date.getHours();
475
+ output += f1('h', (h > 12 ? (h - 12) : (h == 0 ? 12 : h)), 2);
476
+ break;
477
+ case 'H':
478
+ output += f1('H', date.getHours(), 2);
479
+ break;
480
+ case 'i':
481
+ output += f1('i', date.getMinutes(), 2);
482
+ break;
483
+ case 's':
484
+ output += f1('s', date.getSeconds(), 2);
485
+ break;
486
+ case 'a':
487
+ output += date.getHours() > 11 ? 'pm' : 'am';
488
+ break;
489
+ case 'A':
490
+ output += date.getHours() > 11 ? 'PM' : 'AM';
491
+ break;
492
+ case "'":
493
+ if (look("'")) {
494
+ output += "'";
495
+ } else {
496
+ literal = true;
497
+ }
498
+ break;
499
+ default:
500
+ output += format.charAt(i);
501
+ }
502
+ }
503
+ }
504
+ return output;
505
+ };
506
+
507
+ /**
508
+ * Extract a date from a string value with a specified format.
509
+ * @param {String} format - Input format.
510
+ * @param {String} value - String to parse.
511
+ * @param {Object} settings - Settings.
512
+ * @return {Date} - Returns the extracted date.
513
+ */
514
+ ms.parseDate = function (format, value, settings) {
515
+ var def = new Date();
516
+
517
+ if (!format || !value) {
518
+ return def;
519
+ }
520
+
521
+ value = (typeof value == 'object' ? value.toString() : value + '');
522
+
523
+ var s = $.extend({}, defaults, settings),
524
+ shortYearCutoff = s.shortYearCutoff,
525
+ year = def.getFullYear(),
526
+ month = def.getMonth() + 1,
527
+ day = def.getDate(),
528
+ doy = -1,
529
+ hours = def.getHours(),
530
+ minutes = def.getMinutes(),
531
+ seconds = 0, //def.getSeconds(),
532
+ ampm = -1,
533
+ literal = false, // Check whether a format character is doubled
534
+ lookAhead = function (match) {
535
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
536
+ if (matches) {
537
+ iFormat++;
538
+ }
539
+ return matches;
540
+ },
541
+ getNumber = function (match) { // Extract a number from the string value
542
+ lookAhead(match);
543
+ var size = (match == '@' ? 14 : (match == '!' ? 20 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2)))),
544
+ digits = new RegExp('^\\d{1,' + size + '}'),
545
+ num = value.substr(iValue).match(digits);
546
+
547
+ if (!num) {
548
+ return 0;
549
+ }
550
+ //throw 'Missing number at position ' + iValue;
551
+ iValue += num[0].length;
552
+ return parseInt(num[0], 10);
553
+ },
554
+ getName = function (match, s, l) { // Extract a name from the string value and convert to an index
555
+ var names = (lookAhead(match) ? l : s),
556
+ i;
557
+
558
+ for (i = 0; i < names.length; i++) {
559
+ if (value.substr(iValue, names[i].length).toLowerCase() == names[i].toLowerCase()) {
560
+ iValue += names[i].length;
561
+ return i + 1;
562
+ }
563
+ }
564
+ return 0;
565
+ //throw 'Unknown name at position ' + iValue;
566
+ },
567
+ checkLiteral = function () {
568
+ //if (value.charAt(iValue) != format.charAt(iFormat))
569
+ //throw 'Unexpected literal at position ' + iValue;
570
+ iValue++;
571
+ },
572
+ iValue = 0,
573
+ iFormat;
574
+
575
+ for (iFormat = 0; iFormat < format.length; iFormat++) {
576
+ if (literal) {
577
+ if (format.charAt(iFormat) == "'" && !lookAhead("'")) {
578
+ literal = false;
579
+ } else {
580
+ checkLiteral();
581
+ }
582
+ } else {
583
+ switch (format.charAt(iFormat)) {
584
+ case 'd':
585
+ day = getNumber('d');
586
+ break;
587
+ case 'D':
588
+ getName('D', s.dayNamesShort, s.dayNames);
589
+ break;
590
+ case 'o':
591
+ doy = getNumber('o');
592
+ break;
593
+ case 'm':
594
+ month = getNumber('m');
595
+ break;
596
+ case 'M':
597
+ month = getName('M', s.monthNamesShort, s.monthNames);
598
+ break;
599
+ case 'y':
600
+ year = getNumber('y');
601
+ break;
602
+ case 'H':
603
+ hours = getNumber('H');
604
+ break;
605
+ case 'h':
606
+ hours = getNumber('h');
607
+ break;
608
+ case 'i':
609
+ minutes = getNumber('i');
610
+ break;
611
+ case 's':
612
+ seconds = getNumber('s');
613
+ break;
614
+ case 'a':
615
+ ampm = getName('a', ['am', 'pm'], ['am', 'pm']) - 1;
616
+ break;
617
+ case 'A':
618
+ ampm = getName('A', ['am', 'pm'], ['am', 'pm']) - 1;
619
+ break;
620
+ case "'":
621
+ if (lookAhead("'")) {
622
+ checkLiteral();
623
+ } else {
624
+ literal = true;
625
+ }
626
+ break;
627
+ default:
628
+ checkLiteral();
629
+ }
630
+ }
631
+ }
632
+ if (year < 100) {
633
+ year += new Date().getFullYear() - new Date().getFullYear() % 100 +
634
+ (year <= (typeof shortYearCutoff != 'string' ? shortYearCutoff : new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)) ? 0 : -100);
635
+ }
636
+ if (doy > -1) {
637
+ month = 1;
638
+ day = doy;
639
+ do {
640
+ var dim = 32 - new Date(year, month - 1, 32).getDate();
641
+ if (day <= dim) {
642
+ break;
643
+ }
644
+ month++;
645
+ day -= dim;
646
+ } while (true);
647
+ }
648
+ hours = (ampm == -1) ? hours : ((ampm && hours < 12) ? (hours + 12) : (!ampm && hours == 12 ? 0 : hours));
649
+ var date = new Date(year, month - 1, day, hours, minutes, seconds);
650
+ if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) {
651
+ throw 'Invalid date';
652
+ }
653
+ return date;
654
+ };
655
+
656
+ })(jQuery);