Rev 1318 | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*Copyright (c) 2004-2006, The Dojo FoundationAll Rights Reserved.Licensed under the Academic Free License version 2.1 or above OR themodified BSD license. For more information on Dojo licensing, see:http://dojotoolkit.org/community/licensing.shtml*/dojo.provide("dojo.date.format");dojo.require("dojo.date.common");dojo.require("dojo.date.supplemental");dojo.require("dojo.lang.array");dojo.require("dojo.lang.common");dojo.require("dojo.lang.func");dojo.require("dojo.string.common");dojo.require("dojo.i18n.common");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");dojo.requireLocalization("dojo.i18n.calendar", "gregorianExtras", null, "zh,ROOT,ja");(function () {dojo.date.format = function (dateObject, options) {if (typeof options == "string") {dojo.deprecated("dojo.date.format", "To format dates with POSIX-style strings, please use dojo.date.strftime instead", "0.5");return dojo.date.strftime(dateObject, options);}function formatPattern(dateObject, pattern) {return pattern.replace(/([a-z])\1*/ig, function (match) {var s;var c = match.charAt(0);var l = match.length;var pad;var widthList = ["abbr", "wide", "narrow"];switch (c) {case "G":if (l > 3) {dojo.unimplemented("Era format not implemented");}s = info.eras[dateObject.getFullYear() < 0 ? 1 : 0];break;case "y":s = dateObject.getFullYear();switch (l) {case 1:break;case 2:s = String(s).substr(-2);break;default:pad = true;}break;case "Q":case "q":s = Math.ceil((dateObject.getMonth() + 1) / 3);switch (l) {case 1:case 2:pad = true;break;case 3:case 4:dojo.unimplemented("Quarter format not implemented");}break;case "M":case "L":var m = dateObject.getMonth();var width;switch (l) {case 1:case 2:s = m + 1;pad = true;break;case 3:case 4:case 5:width = widthList[l - 3];break;}if (width) {var type = (c == "L") ? "standalone" : "format";var prop = ["months", type, width].join("-");s = info[prop][m];}break;case "w":var firstDay = 0;s = dojo.date.getWeekOfYear(dateObject, firstDay);pad = true;break;case "d":s = dateObject.getDate();pad = true;break;case "D":s = dojo.date.getDayOfYear(dateObject);pad = true;break;case "E":case "e":case "c":var d = dateObject.getDay();var width;switch (l) {case 1:case 2:if (c == "e") {var first = dojo.date.getFirstDayOfWeek(options.locale);d = (d - first + 7) % 7;}if (c != "c") {s = d + 1;pad = true;break;}case 3:case 4:case 5:width = widthList[l - 3];break;}if (width) {var type = (c == "c") ? "standalone" : "format";var prop = ["days", type, width].join("-");s = info[prop][d];}break;case "a":var timePeriod = (dateObject.getHours() < 12) ? "am" : "pm";s = info[timePeriod];break;case "h":case "H":case "K":case "k":var h = dateObject.getHours();switch (c) {case "h":s = (h % 12) || 12;break;case "H":s = h;break;case "K":s = (h % 12);break;case "k":s = h || 24;break;}pad = true;break;case "m":s = dateObject.getMinutes();pad = true;break;case "s":s = dateObject.getSeconds();pad = true;break;case "S":s = Math.round(dateObject.getMilliseconds() * Math.pow(10, l - 3));break;case "v":case "z":s = dojo.date.getTimezoneName(dateObject);if (s) {break;}l = 4;case "Z":var offset = dateObject.getTimezoneOffset();var tz = [(offset <= 0 ? "+" : "-"), dojo.string.pad(Math.floor(Math.abs(offset) / 60), 2), dojo.string.pad(Math.abs(offset) % 60, 2)];if (l == 4) {tz.splice(0, 0, "GMT");tz.splice(3, 0, ":");}s = tz.join("");break;case "Y":case "u":case "W":case "F":case "g":case "A":dojo.debug(match + " modifier not yet implemented");s = "?";break;default:dojo.raise("dojo.date.format: invalid pattern char: " + pattern);}if (pad) {s = dojo.string.pad(s, l);}return s;});}options = options || {};var locale = dojo.hostenv.normalizeLocale(options.locale);var formatLength = options.formatLength || "full";var info = dojo.date._getGregorianBundle(locale);var str = [];var sauce = dojo.lang.curry(this, formatPattern, dateObject);if (options.selector != "timeOnly") {var datePattern = options.datePattern || info["dateFormat-" + formatLength];if (datePattern) {str.push(_processPattern(datePattern, sauce));}}if (options.selector != "dateOnly") {var timePattern = options.timePattern || info["timeFormat-" + formatLength];if (timePattern) {str.push(_processPattern(timePattern, sauce));}}var result = str.join(" ");return result;};dojo.date.parse = function (value, options) {options = options || {};var locale = dojo.hostenv.normalizeLocale(options.locale);var info = dojo.date._getGregorianBundle(locale);var formatLength = options.formatLength || "full";if (!options.selector) {options.selector = "dateOnly";}var datePattern = options.datePattern || info["dateFormat-" + formatLength];var timePattern = options.timePattern || info["timeFormat-" + formatLength];var pattern;if (options.selector == "dateOnly") {pattern = datePattern;} else {if (options.selector == "timeOnly") {pattern = timePattern;} else {if (options.selector == "dateTime") {pattern = datePattern + " " + timePattern;} else {var msg = "dojo.date.parse: Unknown selector param passed: '" + options.selector + "'.";msg += " Defaulting to date pattern.";dojo.debug(msg);pattern = datePattern;}}}var groups = [];var dateREString = _processPattern(pattern, dojo.lang.curry(this, _buildDateTimeRE, groups, info, options));var dateRE = new RegExp("^" + dateREString + "$");var match = dateRE.exec(value);if (!match) {return null;}var widthList = ["abbr", "wide", "narrow"];var result = new Date(1972, 0);var expected = {};for (var i = 1; i < match.length; i++) {var grp = groups[i - 1];var l = grp.length;var v = match[i];switch (grp.charAt(0)) {case "y":if (l != 2) {result.setFullYear(v);expected.year = v;} else {if (v < 100) {v = Number(v);var year = "" + new Date().getFullYear();var century = year.substring(0, 2) * 100;var yearPart = Number(year.substring(2, 4));var cutoff = Math.min(yearPart + 20, 99);var num = (v < cutoff) ? century + v : century - 100 + v;result.setFullYear(num);expected.year = num;} else {if (options.strict) {return null;}result.setFullYear(v);expected.year = v;}}break;case "M":if (l > 2) {if (!options.strict) {v = v.replace(/\./g, "");v = v.toLowerCase();}var months = info["months-format-" + widthList[l - 3]].concat();for (var j = 0; j < months.length; j++) {if (!options.strict) {months[j] = months[j].toLowerCase();}if (v == months[j]) {result.setMonth(j);expected.month = j;break;}}if (j == months.length) {dojo.debug("dojo.date.parse: Could not parse month name: '" + v + "'.");return null;}} else {result.setMonth(v - 1);expected.month = v - 1;}break;case "E":case "e":if (!options.strict) {v = v.toLowerCase();}var days = info["days-format-" + widthList[l - 3]].concat();for (var j = 0; j < days.length; j++) {if (!options.strict) {days[j] = days[j].toLowerCase();}if (v == days[j]) {break;}}if (j == days.length) {dojo.debug("dojo.date.parse: Could not parse weekday name: '" + v + "'.");return null;}break;case "d":result.setDate(v);expected.date = v;break;case "a":var am = options.am || info.am;var pm = options.pm || info.pm;if (!options.strict) {v = v.replace(/\./g, "").toLowerCase();am = am.replace(/\./g, "").toLowerCase();pm = pm.replace(/\./g, "").toLowerCase();}if (options.strict && v != am && v != pm) {dojo.debug("dojo.date.parse: Could not parse am/pm part.");return null;}var hours = result.getHours();if (v == pm && hours < 12) {result.setHours(hours + 12);} else {if (v == am && hours == 12) {result.setHours(0);}}break;case "K":if (v == 24) {v = 0;}case "h":case "H":case "k":if (v > 23) {dojo.debug("dojo.date.parse: Illegal hours value");return null;}result.setHours(v);break;case "m":result.setMinutes(v);break;case "s":result.setSeconds(v);break;case "S":result.setMilliseconds(v);break;default:dojo.unimplemented("dojo.date.parse: unsupported pattern char=" + grp.charAt(0));}}if (expected.year && result.getFullYear() != expected.year) {dojo.debug("Parsed year: '" + result.getFullYear() + "' did not match input year: '" + expected.year + "'.");return null;}if (expected.month && result.getMonth() != expected.month) {dojo.debug("Parsed month: '" + result.getMonth() + "' did not match input month: '" + expected.month + "'.");return null;}if (expected.date && result.getDate() != expected.date) {dojo.debug("Parsed day of month: '" + result.getDate() + "' did not match input day of month: '" + expected.date + "'.");return null;}return result;};function _processPattern(pattern, applyPattern, applyLiteral, applyAll) {var identity = function (x) {return x;};applyPattern = applyPattern || identity;applyLiteral = applyLiteral || identity;applyAll = applyAll || identity;var chunks = pattern.match(/(''|[^'])+/g);var literal = false;for (var i = 0; i < chunks.length; i++) {if (!chunks[i]) {chunks[i] = "";} else {chunks[i] = (literal ? applyLiteral : applyPattern)(chunks[i]);literal = !literal;}}return applyAll(chunks.join(""));}function _buildDateTimeRE(groups, info, options, pattern) {return pattern.replace(/([a-z])\1*/ig, function (match) {var s;var c = match.charAt(0);var l = match.length;switch (c) {case "y":s = "\\d" + ((l == 2) ? "{2,4}" : "+");break;case "M":s = (l > 2) ? "\\S+" : "\\d{1,2}";break;case "d":s = "\\d{1,2}";break;case "E":s = "\\S+";break;case "h":case "H":case "K":case "k":s = "\\d{1,2}";break;case "m":case "s":s = "[0-5]\\d";break;case "S":s = "\\d{1,3}";break;case "a":var am = options.am || info.am || "AM";var pm = options.pm || info.pm || "PM";if (options.strict) {s = am + "|" + pm;} else {s = am;s += (am != am.toLowerCase()) ? "|" + am.toLowerCase() : "";s += "|";s += (pm != pm.toLowerCase()) ? pm + "|" + pm.toLowerCase() : pm;}break;default:dojo.unimplemented("parse of date format, pattern=" + pattern);}if (groups) {groups.push(match);}return "\\s*(" + s + ")\\s*";});}})();dojo.date.strftime = function (dateObject, format, locale) {var padChar = null;function _(s, n) {return dojo.string.pad(s, n || 2, padChar || "0");}var info = dojo.date._getGregorianBundle(locale);function $(property) {switch (property) {case "a":return dojo.date.getDayShortName(dateObject, locale);case "A":return dojo.date.getDayName(dateObject, locale);case "b":case "h":return dojo.date.getMonthShortName(dateObject, locale);case "B":return dojo.date.getMonthName(dateObject, locale);case "c":return dojo.date.format(dateObject, {locale:locale});case "C":return _(Math.floor(dateObject.getFullYear() / 100));case "d":return _(dateObject.getDate());case "D":return $("m") + "/" + $("d") + "/" + $("y");case "e":if (padChar == null) {padChar = " ";}return _(dateObject.getDate());case "f":if (padChar == null) {padChar = " ";}return _(dateObject.getMonth() + 1);case "g":break;case "G":dojo.unimplemented("unimplemented modifier 'G'");break;case "F":return $("Y") + "-" + $("m") + "-" + $("d");case "H":return _(dateObject.getHours());case "I":return _(dateObject.getHours() % 12 || 12);case "j":return _(dojo.date.getDayOfYear(dateObject), 3);case "k":if (padChar == null) {padChar = " ";}return _(dateObject.getHours());case "l":if (padChar == null) {padChar = " ";}return _(dateObject.getHours() % 12 || 12);case "m":return _(dateObject.getMonth() + 1);case "M":return _(dateObject.getMinutes());case "n":return "\n";case "p":return info[dateObject.getHours() < 12 ? "am" : "pm"];case "r":return $("I") + ":" + $("M") + ":" + $("S") + " " + $("p");case "R":return $("H") + ":" + $("M");case "S":return _(dateObject.getSeconds());case "t":return "\t";case "T":return $("H") + ":" + $("M") + ":" + $("S");case "u":return String(dateObject.getDay() || 7);case "U":return _(dojo.date.getWeekOfYear(dateObject));case "V":return _(dojo.date.getIsoWeekOfYear(dateObject));case "W":return _(dojo.date.getWeekOfYear(dateObject, 1));case "w":return String(dateObject.getDay());case "x":return dojo.date.format(dateObject, {selector:"dateOnly", locale:locale});case "X":return dojo.date.format(dateObject, {selector:"timeOnly", locale:locale});case "y":return _(dateObject.getFullYear() % 100);case "Y":return String(dateObject.getFullYear());case "z":var timezoneOffset = dateObject.getTimezoneOffset();return (timezoneOffset > 0 ? "-" : "+") + _(Math.floor(Math.abs(timezoneOffset) / 60)) + ":" + _(Math.abs(timezoneOffset) % 60);case "Z":return dojo.date.getTimezoneName(dateObject);case "%":return "%";}}var string = "";var i = 0;var index = 0;var switchCase = null;while ((index = format.indexOf("%", i)) != -1) {string += format.substring(i, index++);switch (format.charAt(index++)) {case "_":padChar = " ";break;case "-":padChar = "";break;case "0":padChar = "0";break;case "^":switchCase = "upper";break;case "*":switchCase = "lower";break;case "#":switchCase = "swap";break;default:padChar = null;index--;break;}var property = $(format.charAt(index++));switch (switchCase) {case "upper":property = property.toUpperCase();break;case "lower":property = property.toLowerCase();break;case "swap":var compareString = property.toLowerCase();var swapString = "";var j = 0;var ch = "";while (j < property.length) {ch = property.charAt(j);swapString += (ch == compareString.charAt(j)) ? ch.toUpperCase() : ch.toLowerCase();j++;}property = swapString;break;default:break;}switchCase = null;string += property;i = index;}string += format.substring(i);return string;};(function () {var _customFormats = [];dojo.date.addCustomFormats = function (packageName, bundleName) {_customFormats.push({pkg:packageName, name:bundleName});};dojo.date._getGregorianBundle = function (locale) {var gregorian = {};dojo.lang.forEach(_customFormats, function (desc) {var bundle = dojo.i18n.getLocalization(desc.pkg, desc.name, locale);gregorian = dojo.lang.mixin(gregorian, bundle);}, this);return gregorian;};})();dojo.date.addCustomFormats("dojo.i18n.calendar", "gregorian");dojo.date.addCustomFormats("dojo.i18n.calendar", "gregorianExtras");dojo.date.getNames = function (item, type, use, locale) {var label;var lookup = dojo.date._getGregorianBundle(locale);var props = [item, use, type];if (use == "standAlone") {label = lookup[props.join("-")];}props[1] = "format";return (label || lookup[props.join("-")]).concat();};dojo.date.getDayName = function (dateObject, locale) {return dojo.date.getNames("days", "wide", "format", locale)[dateObject.getDay()];};dojo.date.getDayShortName = function (dateObject, locale) {return dojo.date.getNames("days", "abbr", "format", locale)[dateObject.getDay()];};dojo.date.getMonthName = function (dateObject, locale) {return dojo.date.getNames("months", "wide", "format", locale)[dateObject.getMonth()];};dojo.date.getMonthShortName = function (dateObject, locale) {return dojo.date.getNames("months", "abbr", "format", locale)[dateObject.getMonth()];};dojo.date.toRelativeString = function (dateObject) {var now = new Date();var diff = (now - dateObject) / 1000;var end = " ago";var future = false;if (diff < 0) {future = true;end = " from now";diff = -diff;}if (diff < 60) {diff = Math.round(diff);return diff + " second" + (diff == 1 ? "" : "s") + end;}if (diff < 60 * 60) {diff = Math.round(diff / 60);return diff + " minute" + (diff == 1 ? "" : "s") + end;}if (diff < 60 * 60 * 24) {diff = Math.round(diff / 3600);return diff + " hour" + (diff == 1 ? "" : "s") + end;}if (diff < 60 * 60 * 24 * 7) {diff = Math.round(diff / (3600 * 24));if (diff == 1) {return future ? "Tomorrow" : "Yesterday";} else {return diff + " days" + end;}}return dojo.date.format(dateObject);};dojo.date.toSql = function (dateObject, noTime) {return dojo.date.strftime(dateObject, "%F" + !noTime ? " %T" : "");};dojo.date.fromSql = function (sqlDate) {var parts = sqlDate.split(/[\- :]/g);while (parts.length < 6) {parts.push(0);}return new Date(parts[0], (parseInt(parts[1], 10) - 1), parts[2], parts[3], parts[4], parts[5]);};