| /* |
| * Copyright (C) 2004 Baron Schwartz <baron at sequent dot org> |
| * |
| * This program is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU Lesser General Public License as published by the |
| * Free Software Foundation, version 2.1. |
| * |
| * This program is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
| * details. |
| */ |
| |
| Date.parseFunctions = {count:0}; |
| Date.parseRegexes = []; |
| Date.formatFunctions = {count:0}; |
| |
| Date.prototype.dateFormat = function(format) { |
| if (Date.formatFunctions[format] == null) { |
| Date.createNewFormat(format); |
| } |
| var func = Date.formatFunctions[format]; |
| return this[func](); |
| } |
| |
| Date.createNewFormat = function(format) { |
| var funcName = "format" + Date.formatFunctions.count++; |
| Date.formatFunctions[format] = funcName; |
| var code = "Date.prototype." + funcName + " = function(){return "; |
| var special = false; |
| var ch = ''; |
| for (var i = 0; i < format.length; ++i) { |
| ch = format.charAt(i); |
| if (!special && ch == "\\") { |
| special = true; |
| } |
| else if (special) { |
| special = false; |
| code += "'" + String.escape(ch) + "' + "; |
| } |
| else { |
| code += Date.getFormatCode(ch); |
| } |
| } |
| eval(code.substring(0, code.length - 3) + ";}"); |
| } |
| |
| Date.getFormatCode = function(character) { |
| switch (character) { |
| case "d": |
| return "String.leftPad(this.getDate(), 2, '0') + "; |
| case "D": |
| return "Date.dayNames[this.getDay()].substring(0, 3) + "; |
| case "j": |
| return "this.getDate() + "; |
| case "l": |
| return "Date.dayNames[this.getDay()] + "; |
| case "S": |
| return "this.getSuffix() + "; |
| case "w": |
| return "this.getDay() + "; |
| case "z": |
| return "this.getDayOfYear() + "; |
| case "W": |
| return "this.getWeekOfYear() + "; |
| case "F": |
| return "Date.monthNames[this.getMonth()] + "; |
| case "m": |
| return "String.leftPad(this.getMonth() + 1, 2, '0') + "; |
| case "M": |
| return "Date.monthNames[this.getMonth()].substring(0, 3) + "; |
| case "n": |
| return "(this.getMonth() + 1) + "; |
| case "t": |
| return "this.getDaysInMonth() + "; |
| case "L": |
| return "(this.isLeapYear() ? 1 : 0) + "; |
| case "Y": |
| return "this.getFullYear() + "; |
| case "y": |
| return "('' + this.getFullYear()).substring(2, 4) + "; |
| case "a": |
| return "(this.getHours() < 12 ? 'am' : 'pm') + "; |
| case "A": |
| return "(this.getHours() < 12 ? 'AM' : 'PM') + "; |
| case "g": |
| return "((this.getHours() %12) ? this.getHours() % 12 : 12) + "; |
| case "G": |
| return "this.getHours() + "; |
| case "h": |
| return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + "; |
| case "H": |
| return "String.leftPad(this.getHours(), 2, '0') + "; |
| case "i": |
| return "String.leftPad(this.getMinutes(), 2, '0') + "; |
| case "s": |
| return "String.leftPad(this.getSeconds(), 2, '0') + "; |
| case "O": |
| return "this.getGMTOffset() + "; |
| case "T": |
| return "this.getTimezone() + "; |
| case "Z": |
| return "(this.getTimezoneOffset() * -60) + "; |
| default: |
| return "'" + String.escape(character) + "' + "; |
| } |
| } |
| |
| Date.parseDate = function(input, format) { |
| if (Date.parseFunctions[format] == null) { |
| Date.createParser(format); |
| } |
| var func = Date.parseFunctions[format]; |
| return Date[func](input); |
| } |
| |
| Date.createParser = function(format) { |
| var funcName = "parse" + Date.parseFunctions.count++; |
| var regexNum = Date.parseRegexes.length; |
| var currentGroup = 1; |
| Date.parseFunctions[format] = funcName; |
| |
| var code = "Date." + funcName + " = function(input){\n" |
| + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1;\n" |
| + "var d = new Date();\n" |
| + "y = d.getFullYear();\n" |
| + "m = d.getMonth();\n" |
| + "d = d.getDate();\n" |
| + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n" |
| + "if (results && results.length > 0) {" |
| var regex = ""; |
| |
| var special = false; |
| var ch = ''; |
| for (var i = 0; i < format.length; ++i) { |
| ch = format.charAt(i); |
| if (!special && ch == "\\") { |
| special = true; |
| } |
| else if (special) { |
| special = false; |
| regex += String.escape(ch); |
| } |
| else { |
| obj = Date.formatCodeToRegex(ch, currentGroup); |
| currentGroup += obj.g; |
| regex += obj.s; |
| if (obj.g && obj.c) { |
| code += obj.c; |
| } |
| } |
| } |
| |
| code += "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n" |
| + "{return new Date(y, m, d, h, i, s);}\n" |
| + "else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n" |
| + "{return new Date(y, m, d, h, i);}\n" |
| + "else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n" |
| + "{return new Date(y, m, d, h);}\n" |
| + "else if (y > 0 && m >= 0 && d > 0)\n" |
| + "{return new Date(y, m, d);}\n" |
| + "else if (y > 0 && m >= 0)\n" |
| + "{return new Date(y, m);}\n" |
| + "else if (y > 0)\n" |
| + "{return new Date(y);}\n" |
| + "}return null;}"; |
| |
| Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$"); |
| eval(code); |
| } |
| |
| Date.formatCodeToRegex = function(character, currentGroup) { |
| switch (character) { |
| case "D": |
| return {g:0, |
| c:null, |
| s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"}; |
| case "j": |
| case "d": |
| return {g:1, |
| c:"d = parseInt(results[" + currentGroup + "], 10);\n", |
| s:"(\\d{1,2})"}; |
| case "l": |
| return {g:0, |
| c:null, |
| s:"(?:" + Date.dayNames.join("|") + ")"}; |
| case "S": |
| return {g:0, |
| c:null, |
| s:"(?:st|nd|rd|th)"}; |
| case "w": |
| return {g:0, |
| c:null, |
| s:"\\d"}; |
| case "z": |
| return {g:0, |
| c:null, |
| s:"(?:\\d{1,3})"}; |
| case "W": |
| return {g:0, |
| c:null, |
| s:"(?:\\d{2})"}; |
| case "F": |
| return {g:1, |
| c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "].substring(0, 3)], 10);\n", |
| s:"(" + Date.monthNames.join("|") + ")"}; |
| case "M": |
| return {g:1, |
| c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "]], 10);\n", |
| s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"}; |
| case "n": |
| case "m": |
| return {g:1, |
| c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n", |
| s:"(\\d{1,2})"}; |
| case "t": |
| return {g:0, |
| c:null, |
| s:"\\d{1,2}"}; |
| case "L": |
| return {g:0, |
| c:null, |
| s:"(?:1|0)"}; |
| case "Y": |
| return {g:1, |
| c:"y = parseInt(results[" + currentGroup + "], 10);\n", |
| s:"(\\d{4})"}; |
| case "y": |
| return {g:1, |
| c:"var ty = parseInt(results[" + currentGroup + "], 10);\n" |
| + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", |
| s:"(\\d{1,2})"}; |
| case "a": |
| return {g:1, |
| c:"if (results[" + currentGroup + "] == 'am') {\n" |
| + "if (h == 12) { h = 0; }\n" |
| + "} else { if (h < 12) { h += 12; }}", |
| s:"(am|pm)"}; |
| case "A": |
| return {g:1, |
| c:"if (results[" + currentGroup + "] == 'AM') {\n" |
| + "if (h == 12) { h = 0; }\n" |
| + "} else { if (h < 12) { h += 12; }}", |
| s:"(AM|PM)"}; |
| case "g": |
| case "G": |
| case "h": |
| case "H": |
| return {g:1, |
| c:"h = parseInt(results[" + currentGroup + "], 10);\n", |
| s:"(\\d{1,2})"}; |
| case "i": |
| return {g:1, |
| c:"i = parseInt(results[" + currentGroup + "], 10);\n", |
| s:"(\\d{2})"}; |
| case "s": |
| return {g:1, |
| c:"s = parseInt(results[" + currentGroup + "], 10);\n", |
| s:"(\\d{2})"}; |
| case "O": |
| return {g:0, |
| c:null, |
| s:"[+-]\\d{4}"}; |
| case "T": |
| return {g:0, |
| c:null, |
| s:"[A-Z]{3}"}; |
| case "Z": |
| return {g:0, |
| c:null, |
| s:"[+-]\\d{1,5}"}; |
| default: |
| return {g:0, |
| c:null, |
| s:String.escape(character)}; |
| } |
| } |
| |
| Date.prototype.getTimezone = function() { |
| return this.toString().replace( |
| /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace( |
| /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3"); |
| } |
| |
| Date.prototype.getGMTOffset = function() { |
| return (this.getTimezoneOffset() > 0 ? "-" : "+") |
| + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0") |
| + String.leftPad(this.getTimezoneOffset() % 60, 2, "0"); |
| } |
| |
| Date.prototype.getDayOfYear = function() { |
| var num = 0; |
| Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28; |
| for (var i = 0; i < this.getMonth(); ++i) { |
| num += Date.daysInMonth[i]; |
| } |
| return num + this.getDate() - 1; |
| } |
| |
| Date.prototype.getWeekOfYear = function() { |
| // Skip to Thursday of this week |
| var now = this.getDayOfYear() + (4 - this.getDay()); |
| // Find the first Thursday of the year |
| var jan1 = new Date(this.getFullYear(), 0, 1); |
| var then = (7 - jan1.getDay() + 4); |
| document.write(then); |
| return String.leftPad(((now - then) / 7) + 1, 2, "0"); |
| } |
| |
| Date.prototype.isLeapYear = function() { |
| var year = this.getFullYear(); |
| return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year))); |
| } |
| |
| Date.prototype.getFirstDayOfMonth = function() { |
| var day = (this.getDay() - (this.getDate() - 1)) % 7; |
| return (day < 0) ? (day + 7) : day; |
| } |
| |
| Date.prototype.getLastDayOfMonth = function() { |
| var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7; |
| return (day < 0) ? (day + 7) : day; |
| } |
| |
| Date.prototype.getDaysInMonth = function() { |
| Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28; |
| return Date.daysInMonth[this.getMonth()]; |
| } |
| |
| Date.prototype.getSuffix = function() { |
| switch (this.getDate()) { |
| case 1: |
| case 21: |
| case 31: |
| return "st"; |
| case 2: |
| case 22: |
| return "nd"; |
| case 3: |
| case 23: |
| return "rd"; |
| default: |
| return "th"; |
| } |
| } |
| |
| String.escape = function(string) { |
| return string.replace(/('|\\)/g, "\\$1"); |
| } |
| |
| String.leftPad = function (val, size, ch) { |
| var result = new String(val); |
| if (ch == null) { |
| ch = " "; |
| } |
| while (result.length < size) { |
| result = ch + result; |
| } |
| return result; |
| } |
| |
| Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31]; |
| Date.monthNames = |
| ["January", |
| "February", |
| "March", |
| "April", |
| "May", |
| "June", |
| "July", |
| "August", |
| "September", |
| "October", |
| "November", |
| "December"]; |
| Date.dayNames = |
| ["Sunday", |
| "Monday", |
| "Tuesday", |
| "Wednesday", |
| "Thursday", |
| "Friday", |
| "Saturday"]; |
| Date.y2kYear = 50; |
| Date.monthNumbers = { |
| Jan:0, |
| Feb:1, |
| Mar:2, |
| Apr:3, |
| May:4, |
| Jun:5, |
| Jul:6, |
| Aug:7, |
| Sep:8, |
| Oct:9, |
| Nov:10, |
| Dec:11}; |
| Date.patterns = { |
| ISO8601LongPattern:"Y-m-d H:i:s", |
| ISO8601ShortPattern:"Y-m-d", |
| ShortDatePattern: "n/j/Y", |
| LongDatePattern: "l, F d, Y", |
| FullDateTimePattern: "l, F d, Y g:i:s A", |
| MonthDayPattern: "F d", |
| ShortTimePattern: "g:i A", |
| LongTimePattern: "g:i:s A", |
| SortableDateTimePattern: "Y-m-d\\TH:i:s", |
| UniversalSortableDateTimePattern: "Y-m-d H:i:sO", |
| YearMonthPattern: "F, Y"}; |
| |
| var date = new Date("1/1/2007 1:11:11"); |
| |
| for (i = 0; i < 4000; ++i) { |
| var shortFormat = date.dateFormat("Y-m-d"); |
| var longFormat = date.dateFormat("l, F d, Y g:i:s A"); |
| date.setTime(date.getTime() + 84266956); |
| } |