New file |
0,0 → 1,713 |
/* |
Copyright (c) 2004-2006, The Dojo Foundation |
All Rights Reserved. |
|
Licensed under the Academic Free License version 2.1 or above OR the |
modified 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]); |
}; |
|