mobiscroll-rails 2.3.1.0

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