230 lines
6.9 KiB
JavaScript
230 lines
6.9 KiB
JavaScript
|
/*
|
||
|
* Date Format 1.2.3
|
||
|
* (c) 2007-2009 Steven Levithan <stevenlevithan.com>
|
||
|
* MIT license
|
||
|
*
|
||
|
* Includes enhancements by Scott Trenda <scott.trenda.net>
|
||
|
* and Kris Kowal <cixar.com/~kris.kowal/>
|
||
|
*
|
||
|
* Accepts a date, a mask, or a date and a mask.
|
||
|
* Returns a formatted version of the given date.
|
||
|
* The date defaults to the current date/time.
|
||
|
* The mask defaults to dateFormat.masks.default.
|
||
|
*/
|
||
|
|
||
|
(function(global) {
|
||
|
'use strict';
|
||
|
|
||
|
var dateFormat = (function() {
|
||
|
var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZWN]|"[^"]*"|'[^']*'/g;
|
||
|
var timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g;
|
||
|
var timezoneClip = /[^-+\dA-Z]/g;
|
||
|
|
||
|
// Regexes and supporting functions are cached through closure
|
||
|
return function (date, mask, utc, gmt) {
|
||
|
|
||
|
// You can't provide utc if you skip other args (use the 'UTC:' mask prefix)
|
||
|
if (arguments.length === 1 && kindOf(date) === 'string' && !/\d/.test(date)) {
|
||
|
mask = date;
|
||
|
date = undefined;
|
||
|
}
|
||
|
|
||
|
date = date || new Date;
|
||
|
|
||
|
if(!(date instanceof Date)) {
|
||
|
date = new Date(date);
|
||
|
}
|
||
|
|
||
|
if (isNaN(date)) {
|
||
|
throw TypeError('Invalid date');
|
||
|
}
|
||
|
|
||
|
mask = String(dateFormat.masks[mask] || mask || dateFormat.masks['default']);
|
||
|
|
||
|
// Allow setting the utc/gmt argument via the mask
|
||
|
var maskSlice = mask.slice(0, 4);
|
||
|
if (maskSlice === 'UTC:' || maskSlice === 'GMT:') {
|
||
|
mask = mask.slice(4);
|
||
|
utc = true;
|
||
|
if (maskSlice === 'GMT:') {
|
||
|
gmt = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var _ = utc ? 'getUTC' : 'get';
|
||
|
var d = date[_ + 'Date']();
|
||
|
var D = date[_ + 'Day']();
|
||
|
var m = date[_ + 'Month']();
|
||
|
var y = date[_ + 'FullYear']();
|
||
|
var H = date[_ + 'Hours']();
|
||
|
var M = date[_ + 'Minutes']();
|
||
|
var s = date[_ + 'Seconds']();
|
||
|
var L = date[_ + 'Milliseconds']();
|
||
|
var o = utc ? 0 : date.getTimezoneOffset();
|
||
|
var W = getWeek(date);
|
||
|
var N = getDayOfWeek(date);
|
||
|
var flags = {
|
||
|
d: d,
|
||
|
dd: pad(d),
|
||
|
ddd: dateFormat.i18n.dayNames[D],
|
||
|
dddd: dateFormat.i18n.dayNames[D + 7],
|
||
|
m: m + 1,
|
||
|
mm: pad(m + 1),
|
||
|
mmm: dateFormat.i18n.monthNames[m],
|
||
|
mmmm: dateFormat.i18n.monthNames[m + 12],
|
||
|
yy: String(y).slice(2),
|
||
|
yyyy: y,
|
||
|
h: H % 12 || 12,
|
||
|
hh: pad(H % 12 || 12),
|
||
|
H: H,
|
||
|
HH: pad(H),
|
||
|
M: M,
|
||
|
MM: pad(M),
|
||
|
s: s,
|
||
|
ss: pad(s),
|
||
|
l: pad(L, 3),
|
||
|
L: pad(Math.round(L / 10)),
|
||
|
t: H < 12 ? dateFormat.i18n.timeNames[0] : dateFormat.i18n.timeNames[1],
|
||
|
tt: H < 12 ? dateFormat.i18n.timeNames[2] : dateFormat.i18n.timeNames[3],
|
||
|
T: H < 12 ? dateFormat.i18n.timeNames[4] : dateFormat.i18n.timeNames[5],
|
||
|
TT: H < 12 ? dateFormat.i18n.timeNames[6] : dateFormat.i18n.timeNames[7],
|
||
|
Z: gmt ? 'GMT' : utc ? 'UTC' : (String(date).match(timezone) || ['']).pop().replace(timezoneClip, ''),
|
||
|
o: (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
|
||
|
S: ['th', 'st', 'nd', 'rd'][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10],
|
||
|
W: W,
|
||
|
N: N
|
||
|
};
|
||
|
|
||
|
return mask.replace(token, function (match) {
|
||
|
if (match in flags) {
|
||
|
return flags[match];
|
||
|
}
|
||
|
return match.slice(1, match.length - 1);
|
||
|
});
|
||
|
};
|
||
|
})();
|
||
|
|
||
|
dateFormat.masks = {
|
||
|
'default': 'ddd mmm dd yyyy HH:MM:ss',
|
||
|
'shortDate': 'm/d/yy',
|
||
|
'mediumDate': 'mmm d, yyyy',
|
||
|
'longDate': 'mmmm d, yyyy',
|
||
|
'fullDate': 'dddd, mmmm d, yyyy',
|
||
|
'shortTime': 'h:MM TT',
|
||
|
'mediumTime': 'h:MM:ss TT',
|
||
|
'longTime': 'h:MM:ss TT Z',
|
||
|
'isoDate': 'yyyy-mm-dd',
|
||
|
'isoTime': 'HH:MM:ss',
|
||
|
'isoDateTime': 'yyyy-mm-dd\'T\'HH:MM:sso',
|
||
|
'isoUtcDateTime': 'UTC:yyyy-mm-dd\'T\'HH:MM:ss\'Z\'',
|
||
|
'expiresHeaderFormat': 'ddd, dd mmm yyyy HH:MM:ss Z'
|
||
|
};
|
||
|
|
||
|
// Internationalization strings
|
||
|
dateFormat.i18n = {
|
||
|
dayNames: [
|
||
|
'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat',
|
||
|
'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
|
||
|
],
|
||
|
monthNames: [
|
||
|
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
|
||
|
'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'
|
||
|
],
|
||
|
timeNames: [
|
||
|
'a', 'p', 'am', 'pm', 'A', 'P', 'AM', 'PM'
|
||
|
]
|
||
|
};
|
||
|
|
||
|
function pad(val, len) {
|
||
|
val = String(val);
|
||
|
len = len || 2;
|
||
|
while (val.length < len) {
|
||
|
val = '0' + val;
|
||
|
}
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the ISO 8601 week number
|
||
|
* Based on comments from
|
||
|
* http://techblog.procurios.nl/k/n618/news/view/33796/14863/Calculate-ISO-8601-week-and-year-in-javascript.html
|
||
|
*
|
||
|
* @param {Object} `date`
|
||
|
* @return {Number}
|
||
|
*/
|
||
|
function getWeek(date) {
|
||
|
// Remove time components of date
|
||
|
var targetThursday = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
||
|
|
||
|
// Change date to Thursday same week
|
||
|
targetThursday.setDate(targetThursday.getDate() - ((targetThursday.getDay() + 6) % 7) + 3);
|
||
|
|
||
|
// Take January 4th as it is always in week 1 (see ISO 8601)
|
||
|
var firstThursday = new Date(targetThursday.getFullYear(), 0, 4);
|
||
|
|
||
|
// Change date to Thursday same week
|
||
|
firstThursday.setDate(firstThursday.getDate() - ((firstThursday.getDay() + 6) % 7) + 3);
|
||
|
|
||
|
// Check if daylight-saving-time-switch occurred and correct for it
|
||
|
var ds = targetThursday.getTimezoneOffset() - firstThursday.getTimezoneOffset();
|
||
|
targetThursday.setHours(targetThursday.getHours() - ds);
|
||
|
|
||
|
// Number of weeks between target Thursday and first Thursday
|
||
|
var weekDiff = (targetThursday - firstThursday) / (86400000*7);
|
||
|
return 1 + Math.floor(weekDiff);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get ISO-8601 numeric representation of the day of the week
|
||
|
* 1 (for Monday) through 7 (for Sunday)
|
||
|
*
|
||
|
* @param {Object} `date`
|
||
|
* @return {Number}
|
||
|
*/
|
||
|
function getDayOfWeek(date) {
|
||
|
var dow = date.getDay();
|
||
|
if(dow === 0) {
|
||
|
dow = 7;
|
||
|
}
|
||
|
return dow;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* kind-of shortcut
|
||
|
* @param {*} val
|
||
|
* @return {String}
|
||
|
*/
|
||
|
function kindOf(val) {
|
||
|
if (val === null) {
|
||
|
return 'null';
|
||
|
}
|
||
|
|
||
|
if (val === undefined) {
|
||
|
return 'undefined';
|
||
|
}
|
||
|
|
||
|
if (typeof val !== 'object') {
|
||
|
return typeof val;
|
||
|
}
|
||
|
|
||
|
if (Array.isArray(val)) {
|
||
|
return 'array';
|
||
|
}
|
||
|
|
||
|
return {}.toString.call(val)
|
||
|
.slice(8, -1).toLowerCase();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
if (typeof define === 'function' && define.amd) {
|
||
|
define(function () {
|
||
|
return dateFormat;
|
||
|
});
|
||
|
} else if (typeof exports === 'object') {
|
||
|
module.exports = dateFormat;
|
||
|
} else {
|
||
|
global.dateFormat = dateFormat;
|
||
|
}
|
||
|
})(this);
|