Subversion Repositories Applications.papyrus

Rev

Rev 1372 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1318 alexandre_ 1
/*
2
	Copyright (c) 2004-2006, The Dojo Foundation
3
	All Rights Reserved.
4
 
5
	Licensed under the Academic Free License version 2.1 or above OR the
6
	modified BSD license. For more information on Dojo licensing, see:
7
 
8
		http://dojotoolkit.org/community/licensing.shtml
9
*/
10
 
1422 alexandre_ 11
 
12
 
1318 alexandre_ 13
dojo.provide("dojo.date.format");
14
dojo.require("dojo.date.common");
15
dojo.require("dojo.date.supplemental");
16
dojo.require("dojo.lang.array");
17
dojo.require("dojo.lang.common");
18
dojo.require("dojo.lang.func");
19
dojo.require("dojo.string.common");
20
dojo.require("dojo.i18n.common");
1422 alexandre_ 21
dojo.requireLocalization("dojo.i18n.calendar", "gregorian", null, "ko,zh-cn,zh,sv,ja,en,zh-tw,it,hu,nl,fi,zh-hk,fr,pt,ROOT,es,de,pt-br");
22
dojo.requireLocalization("dojo.i18n.calendar", "gregorianExtras", null, "zh,ROOT,ja");
1318 alexandre_ 23
(function () {
24
	dojo.date.format = function (dateObject, options) {
25
		if (typeof options == "string") {
26
			dojo.deprecated("dojo.date.format", "To format dates with POSIX-style strings, please use dojo.date.strftime instead", "0.5");
27
			return dojo.date.strftime(dateObject, options);
28
		}
29
		function formatPattern(dateObject, pattern) {
30
			return pattern.replace(/([a-z])\1*/ig, function (match) {
31
				var s;
32
				var c = match.charAt(0);
33
				var l = match.length;
34
				var pad;
35
				var widthList = ["abbr", "wide", "narrow"];
36
				switch (c) {
37
				  case "G":
38
					if (l > 3) {
39
						dojo.unimplemented("Era format not implemented");
40
					}
41
					s = info.eras[dateObject.getFullYear() < 0 ? 1 : 0];
42
					break;
43
				  case "y":
44
					s = dateObject.getFullYear();
45
					switch (l) {
46
					  case 1:
47
						break;
48
					  case 2:
49
						s = String(s).substr(-2);
50
						break;
51
					  default:
52
						pad = true;
53
					}
54
					break;
55
				  case "Q":
56
				  case "q":
57
					s = Math.ceil((dateObject.getMonth() + 1) / 3);
58
					switch (l) {
59
					  case 1:
60
					  case 2:
61
						pad = true;
62
						break;
63
					  case 3:
64
					  case 4:
65
						dojo.unimplemented("Quarter format not implemented");
66
					}
67
					break;
68
				  case "M":
69
				  case "L":
70
					var m = dateObject.getMonth();
71
					var width;
72
					switch (l) {
73
					  case 1:
74
					  case 2:
75
						s = m + 1;
76
						pad = true;
77
						break;
78
					  case 3:
79
					  case 4:
80
					  case 5:
81
						width = widthList[l - 3];
82
						break;
83
					}
84
					if (width) {
85
						var type = (c == "L") ? "standalone" : "format";
86
						var prop = ["months", type, width].join("-");
87
						s = info[prop][m];
88
					}
89
					break;
90
				  case "w":
91
					var firstDay = 0;
92
					s = dojo.date.getWeekOfYear(dateObject, firstDay);
93
					pad = true;
94
					break;
95
				  case "d":
96
					s = dateObject.getDate();
97
					pad = true;
98
					break;
99
				  case "D":
100
					s = dojo.date.getDayOfYear(dateObject);
101
					pad = true;
102
					break;
103
				  case "E":
104
				  case "e":
105
				  case "c":
106
					var d = dateObject.getDay();
107
					var width;
108
					switch (l) {
109
					  case 1:
110
					  case 2:
111
						if (c == "e") {
112
							var first = dojo.date.getFirstDayOfWeek(options.locale);
113
							d = (d - first + 7) % 7;
114
						}
115
						if (c != "c") {
116
							s = d + 1;
117
							pad = true;
118
							break;
119
						}
120
					  case 3:
121
					  case 4:
122
					  case 5:
123
						width = widthList[l - 3];
124
						break;
125
					}
126
					if (width) {
127
						var type = (c == "c") ? "standalone" : "format";
128
						var prop = ["days", type, width].join("-");
129
						s = info[prop][d];
130
					}
131
					break;
132
				  case "a":
133
					var timePeriod = (dateObject.getHours() < 12) ? "am" : "pm";
134
					s = info[timePeriod];
135
					break;
136
				  case "h":
137
				  case "H":
138
				  case "K":
139
				  case "k":
140
					var h = dateObject.getHours();
141
					switch (c) {
142
					  case "h":
143
						s = (h % 12) || 12;
144
						break;
145
					  case "H":
146
						s = h;
147
						break;
148
					  case "K":
149
						s = (h % 12);
150
						break;
151
					  case "k":
152
						s = h || 24;
153
						break;
154
					}
155
					pad = true;
156
					break;
157
				  case "m":
158
					s = dateObject.getMinutes();
159
					pad = true;
160
					break;
161
				  case "s":
162
					s = dateObject.getSeconds();
163
					pad = true;
164
					break;
165
				  case "S":
166
					s = Math.round(dateObject.getMilliseconds() * Math.pow(10, l - 3));
167
					break;
168
				  case "v":
169
				  case "z":
170
					s = dojo.date.getTimezoneName(dateObject);
171
					if (s) {
172
						break;
173
					}
174
					l = 4;
175
				  case "Z":
176
					var offset = dateObject.getTimezoneOffset();
177
					var tz = [(offset <= 0 ? "+" : "-"), dojo.string.pad(Math.floor(Math.abs(offset) / 60), 2), dojo.string.pad(Math.abs(offset) % 60, 2)];
178
					if (l == 4) {
179
						tz.splice(0, 0, "GMT");
180
						tz.splice(3, 0, ":");
181
					}
182
					s = tz.join("");
183
					break;
184
				  case "Y":
185
				  case "u":
186
				  case "W":
187
				  case "F":
188
				  case "g":
189
				  case "A":
190
					dojo.debug(match + " modifier not yet implemented");
191
					s = "?";
192
					break;
193
				  default:
194
					dojo.raise("dojo.date.format: invalid pattern char: " + pattern);
195
				}
196
				if (pad) {
197
					s = dojo.string.pad(s, l);
198
				}
199
				return s;
200
			});
201
		}
202
		options = options || {};
203
		var locale = dojo.hostenv.normalizeLocale(options.locale);
204
		var formatLength = options.formatLength || "full";
205
		var info = dojo.date._getGregorianBundle(locale);
206
		var str = [];
207
		var sauce = dojo.lang.curry(this, formatPattern, dateObject);
208
		if (options.selector != "timeOnly") {
209
			var datePattern = options.datePattern || info["dateFormat-" + formatLength];
210
			if (datePattern) {
211
				str.push(_processPattern(datePattern, sauce));
212
			}
213
		}
214
		if (options.selector != "dateOnly") {
215
			var timePattern = options.timePattern || info["timeFormat-" + formatLength];
216
			if (timePattern) {
217
				str.push(_processPattern(timePattern, sauce));
218
			}
219
		}
220
		var result = str.join(" ");
221
		return result;
222
	};
223
	dojo.date.parse = function (value, options) {
224
		options = options || {};
225
		var locale = dojo.hostenv.normalizeLocale(options.locale);
226
		var info = dojo.date._getGregorianBundle(locale);
227
		var formatLength = options.formatLength || "full";
228
		if (!options.selector) {
229
			options.selector = "dateOnly";
230
		}
231
		var datePattern = options.datePattern || info["dateFormat-" + formatLength];
232
		var timePattern = options.timePattern || info["timeFormat-" + formatLength];
233
		var pattern;
234
		if (options.selector == "dateOnly") {
235
			pattern = datePattern;
236
		} else {
237
			if (options.selector == "timeOnly") {
238
				pattern = timePattern;
239
			} else {
240
				if (options.selector == "dateTime") {
241
					pattern = datePattern + " " + timePattern;
242
				} else {
243
					var msg = "dojo.date.parse: Unknown selector param passed: '" + options.selector + "'.";
244
					msg += " Defaulting to date pattern.";
245
					dojo.debug(msg);
246
					pattern = datePattern;
247
				}
248
			}
249
		}
250
		var groups = [];
251
		var dateREString = _processPattern(pattern, dojo.lang.curry(this, _buildDateTimeRE, groups, info, options));
252
		var dateRE = new RegExp("^" + dateREString + "$");
253
		var match = dateRE.exec(value);
254
		if (!match) {
255
			return null;
256
		}
257
		var widthList = ["abbr", "wide", "narrow"];
258
		var result = new Date(1972, 0);
259
		var expected = {};
260
		for (var i = 1; i < match.length; i++) {
261
			var grp = groups[i - 1];
262
			var l = grp.length;
263
			var v = match[i];
264
			switch (grp.charAt(0)) {
265
			  case "y":
266
				if (l != 2) {
267
					result.setFullYear(v);
268
					expected.year = v;
269
				} else {
270
					if (v < 100) {
271
						v = Number(v);
272
						var year = "" + new Date().getFullYear();
273
						var century = year.substring(0, 2) * 100;
274
						var yearPart = Number(year.substring(2, 4));
275
						var cutoff = Math.min(yearPart + 20, 99);
276
						var num = (v < cutoff) ? century + v : century - 100 + v;
277
						result.setFullYear(num);
278
						expected.year = num;
279
					} else {
280
						if (options.strict) {
281
							return null;
282
						}
283
						result.setFullYear(v);
284
						expected.year = v;
285
					}
286
				}
287
				break;
288
			  case "M":
289
				if (l > 2) {
290
					if (!options.strict) {
291
						v = v.replace(/\./g, "");
292
						v = v.toLowerCase();
293
					}
294
					var months = info["months-format-" + widthList[l - 3]].concat();
295
					for (var j = 0; j < months.length; j++) {
296
						if (!options.strict) {
297
							months[j] = months[j].toLowerCase();
298
						}
299
						if (v == months[j]) {
300
							result.setMonth(j);
301
							expected.month = j;
302
							break;
303
						}
304
					}
305
					if (j == months.length) {
306
						dojo.debug("dojo.date.parse: Could not parse month name: '" + v + "'.");
307
						return null;
308
					}
309
				} else {
310
					result.setMonth(v - 1);
311
					expected.month = v - 1;
312
				}
313
				break;
314
			  case "E":
315
			  case "e":
316
				if (!options.strict) {
317
					v = v.toLowerCase();
318
				}
319
				var days = info["days-format-" + widthList[l - 3]].concat();
320
				for (var j = 0; j < days.length; j++) {
321
					if (!options.strict) {
322
						days[j] = days[j].toLowerCase();
323
					}
324
					if (v == days[j]) {
325
						break;
326
					}
327
				}
328
				if (j == days.length) {
329
					dojo.debug("dojo.date.parse: Could not parse weekday name: '" + v + "'.");
330
					return null;
331
				}
332
				break;
333
			  case "d":
334
				result.setDate(v);
335
				expected.date = v;
336
				break;
337
			  case "a":
338
				var am = options.am || info.am;
339
				var pm = options.pm || info.pm;
340
				if (!options.strict) {
341
					v = v.replace(/\./g, "").toLowerCase();
342
					am = am.replace(/\./g, "").toLowerCase();
343
					pm = pm.replace(/\./g, "").toLowerCase();
344
				}
345
				if (options.strict && v != am && v != pm) {
346
					dojo.debug("dojo.date.parse: Could not parse am/pm part.");
347
					return null;
348
				}
349
				var hours = result.getHours();
350
				if (v == pm && hours < 12) {
351
					result.setHours(hours + 12);
352
				} else {
353
					if (v == am && hours == 12) {
354
						result.setHours(0);
355
					}
356
				}
357
				break;
358
			  case "K":
359
				if (v == 24) {
360
					v = 0;
361
				}
362
			  case "h":
363
			  case "H":
364
			  case "k":
365
				if (v > 23) {
366
					dojo.debug("dojo.date.parse: Illegal hours value");
367
					return null;
368
				}
369
				result.setHours(v);
370
				break;
371
			  case "m":
372
				result.setMinutes(v);
373
				break;
374
			  case "s":
375
				result.setSeconds(v);
376
				break;
377
			  case "S":
378
				result.setMilliseconds(v);
379
				break;
380
			  default:
381
				dojo.unimplemented("dojo.date.parse: unsupported pattern char=" + grp.charAt(0));
382
			}
383
		}
384
		if (expected.year && result.getFullYear() != expected.year) {
385
			dojo.debug("Parsed year: '" + result.getFullYear() + "' did not match input year: '" + expected.year + "'.");
386
			return null;
387
		}
388
		if (expected.month && result.getMonth() != expected.month) {
389
			dojo.debug("Parsed month: '" + result.getMonth() + "' did not match input month: '" + expected.month + "'.");
390
			return null;
391
		}
392
		if (expected.date && result.getDate() != expected.date) {
393
			dojo.debug("Parsed day of month: '" + result.getDate() + "' did not match input day of month: '" + expected.date + "'.");
394
			return null;
395
		}
396
		return result;
397
	};
398
	function _processPattern(pattern, applyPattern, applyLiteral, applyAll) {
399
		var identity = function (x) {
400
			return x;
401
		};
402
		applyPattern = applyPattern || identity;
403
		applyLiteral = applyLiteral || identity;
404
		applyAll = applyAll || identity;
405
		var chunks = pattern.match(/(''|[^'])+/g);
406
		var literal = false;
407
		for (var i = 0; i < chunks.length; i++) {
408
			if (!chunks[i]) {
409
				chunks[i] = "";
410
			} else {
411
				chunks[i] = (literal ? applyLiteral : applyPattern)(chunks[i]);
412
				literal = !literal;
413
			}
414
		}
415
		return applyAll(chunks.join(""));
416
	}
417
	function _buildDateTimeRE(groups, info, options, pattern) {
418
		return pattern.replace(/([a-z])\1*/ig, function (match) {
419
			var s;
420
			var c = match.charAt(0);
421
			var l = match.length;
422
			switch (c) {
423
			  case "y":
424
				s = "\\d" + ((l == 2) ? "{2,4}" : "+");
425
				break;
426
			  case "M":
427
				s = (l > 2) ? "\\S+" : "\\d{1,2}";
428
				break;
429
			  case "d":
430
				s = "\\d{1,2}";
431
				break;
432
			  case "E":
433
				s = "\\S+";
434
				break;
435
			  case "h":
436
			  case "H":
437
			  case "K":
438
			  case "k":
439
				s = "\\d{1,2}";
440
				break;
441
			  case "m":
442
			  case "s":
443
				s = "[0-5]\\d";
444
				break;
445
			  case "S":
446
				s = "\\d{1,3}";
447
				break;
448
			  case "a":
449
				var am = options.am || info.am || "AM";
450
				var pm = options.pm || info.pm || "PM";
451
				if (options.strict) {
452
					s = am + "|" + pm;
453
				} else {
454
					s = am;
455
					s += (am != am.toLowerCase()) ? "|" + am.toLowerCase() : "";
456
					s += "|";
457
					s += (pm != pm.toLowerCase()) ? pm + "|" + pm.toLowerCase() : pm;
458
				}
459
				break;
460
			  default:
461
				dojo.unimplemented("parse of date format, pattern=" + pattern);
462
			}
463
			if (groups) {
464
				groups.push(match);
465
			}
466
			return "\\s*(" + s + ")\\s*";
467
		});
468
	}
469
})();
470
dojo.date.strftime = function (dateObject, format, locale) {
471
	var padChar = null;
472
	function _(s, n) {
473
		return dojo.string.pad(s, n || 2, padChar || "0");
474
	}
475
	var info = dojo.date._getGregorianBundle(locale);
476
	function $(property) {
477
		switch (property) {
478
		  case "a":
479
			return dojo.date.getDayShortName(dateObject, locale);
480
		  case "A":
481
			return dojo.date.getDayName(dateObject, locale);
482
		  case "b":
483
		  case "h":
484
			return dojo.date.getMonthShortName(dateObject, locale);
485
		  case "B":
486
			return dojo.date.getMonthName(dateObject, locale);
487
		  case "c":
488
			return dojo.date.format(dateObject, {locale:locale});
489
		  case "C":
490
			return _(Math.floor(dateObject.getFullYear() / 100));
491
		  case "d":
492
			return _(dateObject.getDate());
493
		  case "D":
494
			return $("m") + "/" + $("d") + "/" + $("y");
495
		  case "e":
496
			if (padChar == null) {
497
				padChar = " ";
498
			}
499
			return _(dateObject.getDate());
500
		  case "f":
501
			if (padChar == null) {
502
				padChar = " ";
503
			}
504
			return _(dateObject.getMonth() + 1);
505
		  case "g":
506
			break;
507
		  case "G":
508
			dojo.unimplemented("unimplemented modifier 'G'");
509
			break;
510
		  case "F":
511
			return $("Y") + "-" + $("m") + "-" + $("d");
512
		  case "H":
513
			return _(dateObject.getHours());
514
		  case "I":
515
			return _(dateObject.getHours() % 12 || 12);
516
		  case "j":
517
			return _(dojo.date.getDayOfYear(dateObject), 3);
518
		  case "k":
519
			if (padChar == null) {
520
				padChar = " ";
521
			}
522
			return _(dateObject.getHours());
523
		  case "l":
524
			if (padChar == null) {
525
				padChar = " ";
526
			}
527
			return _(dateObject.getHours() % 12 || 12);
528
		  case "m":
529
			return _(dateObject.getMonth() + 1);
530
		  case "M":
531
			return _(dateObject.getMinutes());
532
		  case "n":
533
			return "\n";
534
		  case "p":
535
			return info[dateObject.getHours() < 12 ? "am" : "pm"];
536
		  case "r":
537
			return $("I") + ":" + $("M") + ":" + $("S") + " " + $("p");
538
		  case "R":
539
			return $("H") + ":" + $("M");
540
		  case "S":
541
			return _(dateObject.getSeconds());
542
		  case "t":
543
			return "\t";
544
		  case "T":
545
			return $("H") + ":" + $("M") + ":" + $("S");
546
		  case "u":
547
			return String(dateObject.getDay() || 7);
548
		  case "U":
549
			return _(dojo.date.getWeekOfYear(dateObject));
550
		  case "V":
551
			return _(dojo.date.getIsoWeekOfYear(dateObject));
552
		  case "W":
553
			return _(dojo.date.getWeekOfYear(dateObject, 1));
554
		  case "w":
555
			return String(dateObject.getDay());
556
		  case "x":
557
			return dojo.date.format(dateObject, {selector:"dateOnly", locale:locale});
558
		  case "X":
559
			return dojo.date.format(dateObject, {selector:"timeOnly", locale:locale});
560
		  case "y":
561
			return _(dateObject.getFullYear() % 100);
562
		  case "Y":
563
			return String(dateObject.getFullYear());
564
		  case "z":
565
			var timezoneOffset = dateObject.getTimezoneOffset();
566
			return (timezoneOffset > 0 ? "-" : "+") + _(Math.floor(Math.abs(timezoneOffset) / 60)) + ":" + _(Math.abs(timezoneOffset) % 60);
567
		  case "Z":
568
			return dojo.date.getTimezoneName(dateObject);
569
		  case "%":
570
			return "%";
571
		}
572
	}
573
	var string = "";
574
	var i = 0;
575
	var index = 0;
576
	var switchCase = null;
577
	while ((index = format.indexOf("%", i)) != -1) {
578
		string += format.substring(i, index++);
579
		switch (format.charAt(index++)) {
580
		  case "_":
581
			padChar = " ";
582
			break;
583
		  case "-":
584
			padChar = "";
585
			break;
586
		  case "0":
587
			padChar = "0";
588
			break;
589
		  case "^":
590
			switchCase = "upper";
591
			break;
592
		  case "*":
593
			switchCase = "lower";
594
			break;
595
		  case "#":
596
			switchCase = "swap";
597
			break;
598
		  default:
599
			padChar = null;
600
			index--;
601
			break;
602
		}
603
		var property = $(format.charAt(index++));
604
		switch (switchCase) {
605
		  case "upper":
606
			property = property.toUpperCase();
607
			break;
608
		  case "lower":
609
			property = property.toLowerCase();
610
			break;
611
		  case "swap":
612
			var compareString = property.toLowerCase();
613
			var swapString = "";
614
			var j = 0;
615
			var ch = "";
616
			while (j < property.length) {
617
				ch = property.charAt(j);
618
				swapString += (ch == compareString.charAt(j)) ? ch.toUpperCase() : ch.toLowerCase();
619
				j++;
620
			}
621
			property = swapString;
622
			break;
623
		  default:
624
			break;
625
		}
626
		switchCase = null;
627
		string += property;
628
		i = index;
629
	}
630
	string += format.substring(i);
631
	return string;
632
};
633
(function () {
634
	var _customFormats = [];
635
	dojo.date.addCustomFormats = function (packageName, bundleName) {
636
		_customFormats.push({pkg:packageName, name:bundleName});
637
	};
638
	dojo.date._getGregorianBundle = function (locale) {
639
		var gregorian = {};
640
		dojo.lang.forEach(_customFormats, function (desc) {
641
			var bundle = dojo.i18n.getLocalization(desc.pkg, desc.name, locale);
642
			gregorian = dojo.lang.mixin(gregorian, bundle);
643
		}, this);
644
		return gregorian;
645
	};
646
})();
647
dojo.date.addCustomFormats("dojo.i18n.calendar", "gregorian");
648
dojo.date.addCustomFormats("dojo.i18n.calendar", "gregorianExtras");
649
dojo.date.getNames = function (item, type, use, locale) {
650
	var label;
651
	var lookup = dojo.date._getGregorianBundle(locale);
652
	var props = [item, use, type];
653
	if (use == "standAlone") {
654
		label = lookup[props.join("-")];
655
	}
656
	props[1] = "format";
657
	return (label || lookup[props.join("-")]).concat();
658
};
659
dojo.date.getDayName = function (dateObject, locale) {
660
	return dojo.date.getNames("days", "wide", "format", locale)[dateObject.getDay()];
661
};
662
dojo.date.getDayShortName = function (dateObject, locale) {
663
	return dojo.date.getNames("days", "abbr", "format", locale)[dateObject.getDay()];
664
};
665
dojo.date.getMonthName = function (dateObject, locale) {
666
	return dojo.date.getNames("months", "wide", "format", locale)[dateObject.getMonth()];
667
};
668
dojo.date.getMonthShortName = function (dateObject, locale) {
669
	return dojo.date.getNames("months", "abbr", "format", locale)[dateObject.getMonth()];
670
};
671
dojo.date.toRelativeString = function (dateObject) {
672
	var now = new Date();
673
	var diff = (now - dateObject) / 1000;
674
	var end = " ago";
675
	var future = false;
676
	if (diff < 0) {
677
		future = true;
678
		end = " from now";
679
		diff = -diff;
680
	}
681
	if (diff < 60) {
682
		diff = Math.round(diff);
683
		return diff + " second" + (diff == 1 ? "" : "s") + end;
684
	}
685
	if (diff < 60 * 60) {
686
		diff = Math.round(diff / 60);
687
		return diff + " minute" + (diff == 1 ? "" : "s") + end;
688
	}
689
	if (diff < 60 * 60 * 24) {
690
		diff = Math.round(diff / 3600);
691
		return diff + " hour" + (diff == 1 ? "" : "s") + end;
692
	}
693
	if (diff < 60 * 60 * 24 * 7) {
694
		diff = Math.round(diff / (3600 * 24));
695
		if (diff == 1) {
696
			return future ? "Tomorrow" : "Yesterday";
697
		} else {
698
			return diff + " days" + end;
699
		}
700
	}
701
	return dojo.date.format(dateObject);
702
};
703
dojo.date.toSql = function (dateObject, noTime) {
704
	return dojo.date.strftime(dateObject, "%F" + !noTime ? " %T" : "");
705
};
706
dojo.date.fromSql = function (sqlDate) {
707
	var parts = sqlDate.split(/[\- :]/g);
708
	while (parts.length < 6) {
709
		parts.push(0);
710
	}
711
	return new Date(parts[0], (parseInt(parts[1], 10) - 1), parts[2], parts[3], parts[4], parts[5]);
712
};
713