摘要:javascript Date類的擴展
(function () {
var monthsAbbr = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var monthsFull = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var daysAbbr = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
var daysFull = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var dayNames = {
su: 0,
sun: 0,
sunday: 0,
mo: 1,
mon: 1,
monday: 1,
tu: 2,
tue: 2,
tuesday: 2,
we: 3,
wed: 3,
wednesday: 3,
th: 4,
thu: 4,
thursday: 4,
fr: 5,
fri: 5,
friday: 5,
sa: 6,
sat: 6,
saturday: 6
};
var monthsAll = monthsFull.concat(monthsAbbr);
var daysAll = ["su", "sun", "sunday", "mo", "mon", "monday", "tu", "tue", "tuesday", "we", "wed", "wednesday", "th", "thu", "thursday", "fr", "fri", "friday", "sa", "sat", "saturday"];
var monthNames = {
jan: 0,
january: 0,
feb: 1,
february: 1,
mar: 2,
march: 2,
apr: 3,
april: 3,
may: 4,
jun: 5,
june: 5,
jul: 6,
july: 6,
aug: 7,
august: 7,
sep: 8,
september: 8,
oct: 9,
october: 9,
nov: 10,
november: 10,
dec: 11,
december: 11
};
var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
function pad(str, length) {
str = String(str);
while (str.length < length) {
str = "0" + str
}
return str
}
var isInteger = function (str) {
if (str.match(/^(\d+)$/)) {
return true
}
return false
};
var getInt = function (str, i, minlength, maxlength) {
for (var x = maxlength; x >= minlength; x--) {
var token = str.substring(i, i + x);
if (token.length < minlength) {
return null
}
if (isInteger(token)) {
return token
}
}
return null
};
var origParse = Date.parse;
var getDateFromFormat = function (val, format) {
val = val + "";
format = format + "";
var iVal = 0;
var iFormat = 0;
var c = "";
var token = "";
var token2 = "";
var x, y;
var now = new Date;
var year = now.getYear();
var month = now.getMonth() + 1;
var date = 1;
var hh = 0;
var mm = 0;
var ss = 0;
var ampm = "";
while (iFormat < format.length) {
c = format.charAt(iFormat);
token = "";
while (format.charAt(iFormat) === c && iFormat < format.length) {
token += format.charAt(iFormat++)
}
if (token === "yyyy" || token === "yy" || token === "y") {
if (token === "yyyy") {
x = 4;
y = 4
}
if (token === "yy") {
x = 2;
y = 2
}
if (token === "y") {
x = 2;
y = 4
}
year = getInt(val, iVal, x, y);
if (year === null) {
return NaN
}
iVal += year.length;
if (year.length === 2) {
if (year > 70) {
year = 1900 + (year - 0)
} else {
year = 2e3 + (year - 0)
}
}
} else if (token === "MMM" || token === "NNN") {
month = 0;
for (var i = 0; i < monthsAll.length; i++) {
var monthName = monthsAll[i];
if (val.substring(iVal, iVal + monthName.length).toLowerCase() === monthName.toLowerCase()) {
if (token === "MMM" || token === "NNN" && i > 11) {
month = i + 1;
if (month > 12) {
month -= 12
}
iVal += monthName.length;
break
}
}
}
if (month < 1 || month > 12) {
return NaN
}
} else if (token === "EE" || token === "E") {
for (var n = 0; n < daysAll.length; n++) {
var dayName = daysAll[n];
if (val.substring(iVal, iVal + dayName.length).toLowerCase() === dayName.toLowerCase()) {
iVal += dayName.length;
break
}
}
} else if (token === "MM" || token === "M") {
month = getInt(val, iVal, token.length, 2);
if (month === null || month < 1 || month > 12) {
return NaN
}
iVal += month.length
} else if (token === "dd" || token === "d") {
date = getInt(val, iVal, token.length, 2);
if (date === null || date < 1 || date > 31) {
return NaN
}
iVal += date.length
} else if (token === "hh" || token === "h") {
hh = getInt(val, iVal, token.length, 2);
if (hh === null || hh < 1 || hh > 12) {
return NaN
}
iVal += hh.length
} else if (token === "HH" || token === "H") {
hh = getInt(val, iVal, token.length, 2);
if (hh === null || hh < 0 || hh > 23) {
return NaN
}
iVal += hh.length
} else if (token === "KK" || token === "K") {
hh = getInt(val, iVal, token.length, 2);
if (hh === null || hh < 0 || hh > 11) {
return NaN
}
iVal += hh.length
} else if (token === "kk" || token === "k") {
hh = getInt(val, iVal, token.length, 2);
if (hh === null || hh < 1 || hh > 24) {
return NaN
}
iVal += hh.length;
hh--
} else if (token === "mm" || token === "m") {
mm = getInt(val, iVal, token.length, 2);
if (mm === null || mm < 0 || mm > 59) {
return NaN
}
iVal += mm.length
} else if (token === "ss" || token === "s") {
ss = getInt(val, iVal, token.length, 2);
if (ss === null || ss < 0 || ss > 59) {
return NaN
}
iVal += ss.length
} else if (token === "a") {
if (val.substring(iVal, iVal + 2).toLowerCase() === "am") {
ampm = "AM"
} else if (val.substring(iVal, iVal + 2).toLowerCase() === "pm") {
ampm = "PM"
} else {
return NaN
}
iVal += 2
} else {
if (val.substring(iVal, iVal + token.length) !== token) {
return NaN
} else {
iVal += token.length
}
}
}
if (iVal !== val.length) {
return NaN
}
if (month === 2) {
if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) {
if (date > 29) {
return NaN
}
} else {
if (date > 28) {
return NaN
}
}
}
if (month === 4 || month === 6 || month === 9 || month === 11) {
if (date > 30) {
return NaN
}
}
if (hh < 12 && ampm === "PM") {
hh = hh - 0 + 12
} else if (hh > 11 && ampm === "AM") {
hh -= 12
}
var newdate = new Date(year, month - 1, date, hh, mm, ss);
return newdate.getTime()
};
Date.parse = function (date, format) {
if (format) {
return getDateFromFormat(date, format)
}
var timestamp = origParse(date),
minutesOffset = 0,
match;
if (isNaN(timestamp) && (match = /^(\d{4}|[+\-]\d{6})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?))?/.exec(date))) {
if (match[8] !== "Z") {
minutesOffset = +match[10] * 60 + +match[11];
if (match[9] === "+") {
minutesOffset = 0 - minutesOffset
}
}
match[7] = match[7] || "000";
timestamp = Date.UTC(+match[1], +match[2] - 1, +match[3], +match[4], +match[5] + minutesOffset, +match[6], +match[7].substr(0, 3))
}
return timestamp
};
function polyfill(name, func) {
if (Date.prototype[name] === undefined) {
Date.prototype[name] = func
}
}
Date.today = function () {
return (new Date).clearTime()
};
Date.UTCtoday = function () {
return (new Date).clearUTCTime()
};
Date.tomorrow = function () {
return Date.today().add({
days: 1
})
};
Date.UTCtomorrow = function () {
return Date.UTCtoday().add({
days: 1
})
};
Date.yesterday = function () {
return Date.today().add({
days: -1
})
};
Date.UTCyesterday = function () {
return Date.UTCtoday().add({
days: -1
})
};
Date.validateDay = function (day, year, month) {
var date = new Date(year, month, day);
return date.getFullYear() === year && date.getMonth() === month && date.getDate() === day
};
Date.validateYear = function (year) {
return year >= 0 && year <= 9999
};
Date.validateSecond = function (second) {
return second >= 0 && second < 60
};
Date.validateMonth = function (month) {
return month >= 0 && month < 12
};
Date.validateMinute = function (minute) {
return minute >= 0 && minute < 60
};
Date.validateMillisecond = function (milli) {
return milli >= 0 && milli < 1e3
};
Date.validateHour = function (hour) {
return hour >= 0 && hour < 24
};
Date.compare = function (date1, date2) {
if (date1.valueOf() < date2.valueOf()) {
return -1
} else if (date1.valueOf() > date2.valueOf()) {
return 1
}
return 0
};
Date.equals = function (date1, date2) {
return date1.valueOf() === date2.valueOf()
};
Date.equalsDay = function (date1, date2) {
return date1.toYMD() === date2.toYMD()
};
Date.getDayNumberFromName = function (name) {
return dayNames[name.toLowerCase()]
};
Date.getMonthNumberFromName = function (name) {
return monthNames[name.toLowerCase()]
};
Date.getMonthNameFromNumber = function (number) {
return monthsFull[number]
};
Date.getMonthAbbrFromNumber = function (number) {
return monthsAbbr[number]
};
Date.isLeapYear = function (year) {
return new Date(year, 1, 29).getDate() === 29
};
Date.getDaysInMonth = function (year, month) {
if (month === 1) {
return Date.isLeapYear(year) ? 29 : 28
}
return daysInMonth[month]
};
polyfill("getMonthAbbr", function () {
return monthsAbbr[this.getMonth()]
});
polyfill("getMonthName", function () {
return monthsFull[this.getMonth()]
});
polyfill("getLastMonthName", function () {
var i = this.getMonth();
i = i == 0 ? 11 : i - 1;
return monthsFull[i]
});
polyfill("getUTCOffset", function () {
var tz = pad(Math.abs(this.getTimezoneOffset() / .6), 4);
if (this.getTimezoneOffset() > 0) {
tz = "-" + tz
}
return tz
});
polyfill("toCLFString", function () {
return pad(this.getDate(), 2) + "/" + this.getMonthAbbr() + "/" + this.getFullYear() + ":" + pad(this.getHours(), 2) + ":" + pad(this.getMinutes(), 2) + ":" + pad(this.getSeconds(), 2) + " " + this.getUTCOffset()
});
polyfill("toYMD", function (separator) {
separator = typeof separator === "undefined" ? "-" : separator;
return this.getFullYear() + separator + pad(this.getMonth() + 1, 2) + separator + pad(this.getDate(), 2)
});
polyfill("toDBString", function () {
return this.getUTCFullYear() + "-" + pad(this.getUTCMonth() + 1, 2) + "-" + pad(this.getUTCDate(), 2) + " " + pad(this.getUTCHours(), 2) + ":" + pad(this.getUTCMinutes(), 2) + ":" + pad(this.getUTCSeconds(), 2)
});
polyfill("clearTime", function () {
this.setHours(0);
this.setMinutes(0);
this.setSeconds(0);
this.setMilliseconds(0);
return this
});
polyfill("clearUTCTime", function () {
this.setUTCHours(0);
this.setUTCMinutes(0);
this.setUTCSeconds(0);
this.setUTCMilliseconds(0);
return this
});
polyfill("add", function (obj) {
if (obj.milliseconds !== undefined) {
this.setMilliseconds(this.getMilliseconds() + obj.milliseconds)
}
if (obj.seconds !== undefined) {
this.setSeconds(this.getSeconds() + obj.seconds)
}
if (obj.minutes !== undefined) {
this.setMinutes(this.getMinutes() + obj.minutes)
}
if (obj.hours !== undefined) {
this.setHours(this.getHours() + obj.hours)
}
if (obj.days !== undefined) {
this.setDate(this.getDate() + obj.days)
}
if (obj.weeks !== undefined) {
this.setDate(this.getDate() + obj.weeks * 7)
}
if (obj.months !== undefined) {
this.setMonth(this.getMonth() + obj.months)
}
if (obj.years !== undefined) {
this.setFullYear(this.getFullYear() + obj.years)
}
return this
});
polyfill("addMilliseconds", function (milliseconds) {
return this.add({
milliseconds: milliseconds
})
});
polyfill("addSeconds", function (seconds) {
return this.add({
seconds: seconds
})
});
polyfill("addMinutes", function (minutes) {
return this.add({
minutes: minutes
})
});
polyfill("addHours", function (hours) {
return this.add({
hours: hours
})
});
polyfill("addDays", function (days) {
return this.add({
days: days
})
});
polyfill("addWeeks", function (weeks) {
return this.add({
days: weeks * 7
})
});
polyfill("addMonths", function (months) {
return this.add({
months: months
})
});
polyfill("addYears", function (years) {
return this.add({
years: years
})
});
polyfill("remove", function (obj) {
if (obj.seconds !== undefined) {
this.setSeconds(this.getSeconds() - obj.seconds)
}
if (obj.minutes !== undefined) {
this.setMinutes(this.getMinutes() - obj.minutes)
}
if (obj.hours !== undefined) {
this.setHours(this.getHours() - obj.hours)
}
if (obj.days !== undefined) {
this.setDate(this.getDate() - obj.days)
}
if (obj.weeks !== undefined) {
this.setDate(this.getDate() - obj.weeks * 7)
}
if (obj.months !== undefined) {
this.setMonth(this.getMonth() - obj.months)
}
if (obj.years !== undefined) {
this.setFullYear(this.getFullYear() - obj.years)
}
return this
});
polyfill("removeMilliseconds", function (milliseconds) {
throw new Error("Not implemented")
});
polyfill("removeSeconds", function (seconds) {
return this.remove({
seconds: seconds
})
});
polyfill("removeMinutes", function (minutes) {
return this.remove({
minutes: minutes
})
});
polyfill("removeHours", function (hours) {
return this.remove({
hours: hours
})
});
polyfill("removeDays", function (days) {
return this.remove({
days: days
})
});
polyfill("removeWeeks", function (weeks) {
return this.remove({
days: weeks * 7
})
});
polyfill("removeMonths", function (months) {
return this.remove({
months: months
})
});
polyfill("removeYears", function (years) {
return this.remove({
years: years
})
});
polyfill("addWeekdays", function (weekdays) {
var day = this.getDay();
if (day === 0) {
day = 7
}
var daysOffset = weekdays;
var weekspan = Math.floor((weekdays + day - 1) / 5);
if (weekdays > 0) {
daysOffset += weekspan * 2;
if (day > 5) {
daysOffset -= day - 5
}
} else {
daysOffset += Math.min(weekspan * 2, 0);
if (day > 6) {
daysOffset -= 1
}
}
return this.addDays(daysOffset)
});
polyfill("setTimeToNow", function () {
var n = new Date;
this.setMilliseconds(n.getMilliseconds());
this.setSeconds(n.getSeconds());
this.setMinutes(n.getMinutes());
this.setHours(n.getHours())
});
polyfill("clone", function () {
return new Date(this.valueOf())
});
polyfill("between", function (start, end) {
return this.valueOf() >= start.valueOf() && this.valueOf() <= end.valueOf()
});
polyfill("compareTo", function (date) {
return Date.compare(this, date)
});
polyfill("equals", function (date) {
return Date.equals(this, date)
});
polyfill("equalsDay", function (date) {
return Date.equalsDay(this, date)
});
polyfill("isToday", function () {
return Date.equalsDay(this, Date.today())
});
polyfill("isAfter", function (date) {
date = date ? date : new Date;
return this.compareTo(date) > 0
});
polyfill("isBefore", function (date) {
date = date ? date : new Date;
return this.compareTo(date) < 0
});
polyfill("isWeekend", function (date) {
return this.getDay() % 6 === 0
});
polyfill("getDaysBetween", function (date) {
return (date.clone().valueOf() - this.valueOf()) / 864e5 | 0
});
polyfill("getHoursBetween", function (date) {
return (date.clone().valueOf() - this.valueOf()) / 36e5 | 0
});
polyfill("getMinutesBetween", function (date) {
return (date.clone().valueOf() - this.valueOf()) / 6e4 | 0
});
polyfill("getSecondsBetween", function (date) {
return (date.clone().valueOf() - this.valueOf()) / 1e3 | 0
});
polyfill("getMillisecondsBetween", function (date) {
return date.clone().valueOf() - this.valueOf() | 0
});
polyfill("getMonthsBetween", function (date) {
var daysDiff, daysInMonth, months = Math.ceil(new Date(date - this).getUTCDate() / 31),
testDate = new Date(this.getTime()),
totalDays = Date.getDaysInMonth;
testDate.setUTCMonth(testDate.getUTCMonth() + months);
while (testDate.getTime() < date.getTime()) {
testDate.setUTCMonth(testDate.getUTCMonth() + 1);
months++
}
if (testDate.getTime() !== date.getTime()) {
testDate.setUTCMonth(testDate.getUTCMonth() - 1);
months--
}
if (date.getUTCMonth() === testDate.getUTCMonth()) {
daysDiff = new Date(date - testDate).getUTCDate();
daysInMonth = totalDays(testDate.getUTCFullYear(), testDate.getUTCMonth());
return months + daysDiff / daysInMonth
} else {
daysInMonth = totalDays(testDate.getUTCFullYear(), testDate.getUTCMonth());
daysDiff = daysInMonth - testDate.getUTCDate() + 1;
return months + +(daysDiff / daysInMonth).toFixed(5) + +(date.getUTCDate() / totalDays(date.getUTCFullYear(), date.getUTCMonth())).toFixed(5)
}
});
polyfill("getOrdinalNumber", function () {
return Math.ceil((this.clone().clearTime() - new Date(this.getFullYear(), 0, 1)) / 864e5) + 1
});
polyfill("toFormat", function (format) {
return toFormat(format, getReplaceMap(this))
});
polyfill("toUTCFormat", function (format) {
return toFormat(format, getUTCReplaceMap(this))
});
polyfill("getWeekNumber", function () {
var onejan = new Date(this.getFullYear(), 0, 1);
return Math.ceil(((this - onejan) / 864e5 + onejan.getDay() + 1) / 7)
});
polyfill("getFullWeekNumber", function () {
var weekNumber = "" + this.getWeekNumber();
if (weekNumber.length === 1) {
weekNumber = "0" + weekNumber
}
return weekNumber
});
var toFormat = function (format, replaceMap) {
var f = [format],
i, l, s;
var replace = function (str, rep) {
var i = 0,
l = f.length,
j, ll, t, n = [];
for (; i < l; i++) {
if (typeof f[i] == "string") {
t = f[i].split(str);
for (j = 0, ll = t.length - 1; j < ll; j++) {
n.push(t[j]);
n.push([rep])
}
n.push(t[ll])
} else {
n.push(f[i])
}
}
f = n
};
for (i in replaceMap) {
replace(i, replaceMap[i])
}
s = "";
for (i = 0, l = f.length; i < l; i++) s += typeof f[i] == "string" ? f[i] : f[i][0];
return f.join("")
};
var getReplaceMap = function (date) {
var hours = date.getHours() % 12 ? date.getHours() % 12 : 12;
return {
YYYY: date.getFullYear(),
YY: String(date.getFullYear()).slice(-2),
MMMM: monthsFull[date.getMonth()],
MMM: monthsAbbr[date.getMonth()],
MM: pad(date.getMonth() + 1, 2),
MI: pad(date.getMinutes(), 2),
M: date.getMonth() + 1,
DDDD: daysFull[date.getDay()],
DDD: daysAbbr[date.getDay()],
DD: pad(date.getDate(), 2),
D: date.getDate(),
HH24: pad(date.getHours(), 2),
HH: pad(hours, 2),
H: hours,
SS: pad(date.getSeconds(), 2),
PP: date.getHours() >= 12 ? "PM" : "AM",
P: date.getHours() >= 12 ? "pm" : "am",
LL: pad(date.getMilliseconds(), 3)
}
};
var getUTCReplaceMap = function (date) {
var hours = date.getUTCHours() % 12 ? date.getUTCHours() % 12 : 12;
return {
YYYY: date.getUTCFullYear(),
YY: String(date.getUTCFullYear()).slice(-2),
MMMM: monthsFull[date.getUTCMonth()],
MMM: monthsAbbr[date.getUTCMonth()],
MM: pad(date.getUTCMonth() + 1, 2),
MI: pad(date.getUTCMinutes(), 2),
M: date.getUTCMonth() + 1,
DDDD: daysFull[date.getUTCDay()],
DDD: daysAbbr[date.getUTCDay()],
DD: pad(date.getUTCDate(), 2),
D: date.getUTCDate(),
HH24: pad(date.getUTCHours(), 2),
HH: pad(hours, 2),
H: hours,
SS: pad(date.getUTCSeconds(), 2),
PP: date.getUTCHours() >= 12 ? "PM" : "AM",
P: date.getUTCHours() >= 12 ? "pm" : "am",
LL: pad(date.getUTCMilliseconds(), 3)
}
}
})();