in globalize/globalize.ts [455:691]
formatDate = function (value, format, culture) {
var cal = culture.calendar,
convert = cal.convert;
if (!format || !format.length || format === "i") {
var ret;
if (culture && culture.name.length) {
if (convert) {
// non-gregorian calendar, so we cannot use built-in toLocaleString()
ret = formatDate(value, cal.patterns.F, culture);
}
else {
var eraDate = new Date(value.getTime()),
era = getEra(value, cal.eras);
eraDate.setFullYear(getEraYear(value, cal, era));
ret = eraDate.toLocaleString();
}
}
else {
ret = value.toString();
}
return ret;
}
var eras = cal.eras,
sortable = format === "s";
format = expandFormat(cal, format);
// Start with an empty string
ret = [];
var hour,
zeros = ["0", "00", "000"],
foundDay,
checkedDay,
dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g,
quoteCount = 0,
tokenRegExp = getTokenRegExp(),
converted;
function padZeros(num, c) {
var r, s = num + "";
if (c > 1 && s.length < c) {
r = (zeros[c - 2] + s);
return r.substr(r.length - c, c);
}
else {
r = s;
}
return r;
}
function hasDay() {
if (foundDay || checkedDay) {
return foundDay;
}
foundDay = dayPartRegExp.test(format);
checkedDay = true;
return foundDay;
}
function getPart(date, part) {
if (converted) {
return converted[part];
}
switch (part) {
case 0: return date.getFullYear();
case 1: return date.getMonth();
case 2: return date.getDate();
}
}
if (!sortable && convert) {
converted = convert.fromGregorian(value);
}
for (; ;) {
// Save the current index
var index = tokenRegExp.lastIndex,
// Look for the next pattern
ar = tokenRegExp.exec(format);
// Append the text before the pattern (or the end of the string if not found)
var preMatch = format.slice(index, ar ? ar.index : format.length);
quoteCount += appendPreOrPostMatch(preMatch, ret);
if (!ar) {
break;
}
// do not replace any matches that occur inside a string literal.
if (quoteCount % 2) {
ret.push(ar[0]);
continue;
}
var current = ar[0],
clength = current.length;
switch (current) {
case "ddd":
//Day of the week, as a three-letter abbreviation
case "dddd":
// Day of the week, using the full name
var names = (clength === 3) ? cal.days.namesAbbr : cal.days.names;
ret.push(names[value.getDay()]);
break;
case "d":
// Day of month, without leading zero for single-digit days
case "dd":
// Day of month, with leading zero for single-digit days
foundDay = true;
ret.push(
padZeros(getPart(value, 2), clength)
);
break;
case "MMM":
// Month, as a three-letter abbreviation
case "MMMM":
// Month, using the full name
var part = getPart(value, 1);
ret.push(
(cal.monthsGenitive && hasDay())
?
cal.monthsGenitive[clength === 3 ? "namesAbbr" : "names"][part]
:
cal.months[clength === 3 ? "namesAbbr" : "names"][part]
);
break;
case "M":
// Month, as digits, with no leading zero for single-digit months
case "MM":
// Month, as digits, with leading zero for single-digit months
ret.push(
padZeros(getPart(value, 1) + 1, clength)
);
break;
case "y":
// Year, as two digits, but with no leading zero for years less than 10
case "yy":
// Year, as two digits, with leading zero for years less than 10
case "yyyy":
// Year represented by four full digits
part = converted ? converted[0] : getEraYear(value, cal, getEra(value, eras), sortable);
if (clength < 4) {
part = part % 100;
}
ret.push(
padZeros(part, clength)
);
break;
case "h":
// Hours with no leading zero for single-digit hours, using 12-hour clock
case "hh":
// Hours with leading zero for single-digit hours, using 12-hour clock
hour = value.getHours() % 12;
if (hour === 0) hour = 12;
ret.push(
padZeros(hour, clength)
);
break;
case "H":
// Hours with no leading zero for single-digit hours, using 24-hour clock
case "HH":
// Hours with leading zero for single-digit hours, using 24-hour clock
ret.push(
padZeros(value.getHours(), clength)
);
break;
case "m":
// Minutes with no leading zero for single-digit minutes
case "mm":
// Minutes with leading zero for single-digit minutes
ret.push(
padZeros(value.getMinutes(), clength)
);
break;
case "s":
// Seconds with no leading zero for single-digit seconds
case "ss":
// Seconds with leading zero for single-digit seconds
ret.push(
padZeros(value.getSeconds(), clength)
);
break;
case "t":
// One character am/pm indicator ("a" or "p")
case "tt":
// Multicharacter am/pm indicator
part = value.getHours() < 12 ? (cal.AM ? cal.AM[0] : " ") : (cal.PM ? cal.PM[0] : " ");
ret.push(clength === 1 ? part.charAt(0) : part);
break;
case "f":
// Deciseconds
case "ff":
// Centiseconds
case "fff":
// Milliseconds
ret.push(
padZeros(value.getMilliseconds(), 3).substr(0, clength)
);
break;
case "z":
// Time zone offset, no leading zero
case "zz":
// Time zone offset with leading zero
hour = value.getTimezoneOffset() / 60;
ret.push(
(hour <= 0 ? "+" : "-") + padZeros(Math.floor(Math.abs(hour)), clength)
);
break;
case "zzz":
// Time zone offset with leading zero
hour = value.getTimezoneOffset() / 60;
ret.push(
(hour <= 0 ? "+" : "-") + padZeros(Math.floor(Math.abs(hour)), 2)
// Hard coded ":" separator, rather than using cal.TimeSeparator
// Repeated here for consistency, plus ":" was already assumed in date parsing.
+ ":" + padZeros(Math.abs(value.getTimezoneOffset() % 60), 2)
);
break;
case "g":
case "gg":
if (cal.eras) {
ret.push(
cal.eras[getEra(value, eras)].name
);
}
break;
case "/":
ret.push(cal["/"]);
break;
default:
throw "Invalid date format pattern \'" + current + "\'.";
}
}
return ret.join("");
};