1// =================================================================== 2// Author: Matt Kruse <[email protected]> 3// WWW: http://www.mattkruse.com/ 4// 5// NOTICE: You may use this code for any purpose, commercial or 6// private, without any further permission from the author. You may 7// remove this notice from your final code if you wish, however it is 8// appreciated by the author if at least my web site address is kept. 9// 10// You may *NOT* re-distribute this code in any way except through its 11// use. That means, you can include it in your product, or your web 12// site, or any other form where the code is actually being used. You 13// may not put the plain javascript up on your site for download or 14// include it in your javascript libraries for download. 15// If you wish to share this code with others, please just point them 16// to the URL instead. 17// Please DO NOT link directly to my .js files from your site. Copy 18// the files to your server and use them there. Thank you. 19// =================================================================== 20 21// HISTORY 22// ------------------------------------------------------------------ 23// May 17, 2003: Fixed bug in parseDate() for dates <1970 24// March 11, 2003: Added parseDate() function 25// March 11, 2003: Added "NNN" formatting option. Doesn't match up 26// perfectly with SimpleDateFormat formats, but 27// backwards-compatability was required. 28 29// ------------------------------------------------------------------ 30// These functions use the same 'format' strings as the 31// java.text.SimpleDateFormat class, with minor exceptions. 32// The format string consists of the following abbreviations: 33// 34// Field | Full Form | Short Form 35// -------------+--------------------+----------------------- 36// Year | yyyy (4 digits) | yy (2 digits), y (2 or 4 digits) 37// Month | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits) 38// | NNN (abbr.) | 39// Day of Month | dd (2 digits) | d (1 or 2 digits) 40// Day of Week | EE (name) | E (abbr) 41// Hour (1-12) | hh (2 digits) | h (1 or 2 digits) 42// Hour (0-23) | HH (2 digits) | H (1 or 2 digits) 43// Hour (0-11) | KK (2 digits) | K (1 or 2 digits) 44// Hour (1-24) | kk (2 digits) | k (1 or 2 digits) 45// Minute | mm (2 digits) | m (1 or 2 digits) 46// Second | ss (2 digits) | s (1 or 2 digits) 47// AM/PM | a | 48// 49// NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm! 50// Examples: 51// "MMM d, y" matches: January 01, 2000 52// Dec 1, 1900 53// Nov 20, 00 54// "M/d/yy" matches: 01/20/00 55// 9/2/00 56// "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM" 57// ------------------------------------------------------------------ 58 59var MONTH_NAMES = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); 60var DAY_NAMES = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); 61function LZ(x) { return (x < 0 || x > 9 ? "" : "0") + x } 62 63// ------------------------------------------------------------------ 64// isDate ( date_string, format_string ) 65// Returns true if date string matches format of format string and 66// is a valid date. Else returns false. 67// It is recommended that you trim whitespace around the value before 68// passing it to this function, as whitespace is NOT ignored! 69// ------------------------------------------------------------------ 70function isDate(val, format) { 71 var date = getDateFromFormat(val, format); 72 if (date == 0) { return false; } 73 return true; 74} 75 76// ------------------------------------------------------------------- 77// compareDates(date1,date1format,date2,date2format) 78// Compare two date strings to see which is greater. 79// Returns: 80// 1 if date1 is greater than date2
81// 0 if date2 is greater than date1 of if they are the same 82// -1 if either of the dates is in an invalid format 83// ------------------------------------------------------------------- 84function compareDates(date1, dateformat1, date2, dateformat2) { 85 var d1 = getDateFromFormat(date1, dateformat1); 86 var d2 = getDateFromFormat(date2, dateformat2); 87 if (d1 == 0 || d2 == 0) { 88 return -1; 89 } 90 else if (d1 > d2) { 91 return 1; 92 } 93 return 0; 94} 95 96// ------------------------------------------------------------------ 97// formatDate (date_object, format) 98// Returns a date in the output format specified. 99// The format string uses the same abbreviations as in getDateFromFormat() 100// ------------------------------------------------------------------ 101function formatDate(date, format) { 102 format = format + ""; 103 var result = ""; 104 var i_format = 0; 105 var c = ""; 106 var token = ""; 107 var y = date.getYear() + ""; 108 var M = date.getMonth() + 1; 109 var d = date.getDate(); 110 var E = date.getDay(); 111 var H = date.getHours(); 112 var m = date.getMinutes(); 113 var s = date.getSeconds(); 114 var yyyy, yy, MMM, MM, dd, hh, h, mm, ss, ampm, HH, H, KK, K, kk, k; 115 // Convert real date parts into formatted versions 116 var value = new Object(); 117 if (y.length < 4) { y = "" + (y - 0 + 1900); } 118 value["y"] = "" + y; 119 value["yyyy"] = y; 120 value["yy"] = y.substring(2, 4); 121 value["M"] = M; 122 value["MM"] = LZ(M); 123 value["MMM"] = MONTH_NAMES[M - 1]; 124 value["NNN"] = MONTH_NAMES[M + 11]; 125 value["d"] = d; 126 value["dd"] = LZ(d); 127 value["E"] = DAY_NAMES[E + 7]; 128 value["EE"] = DAY_NAMES[E]; 129 value["H"] = H; 130 value["HH"] = LZ(H); 131 if (H == 0) { value["h"] = 12; } 132 else if (H > 12) { value["h"] = H - 12; } 133 else { value["h"] = H; } 134 value["hh"] = LZ(value["h"]); 135 if (H > 11) { value["K"] = H - 12; } else { value["K"] = H; } 136 value["k"] = H + 1; 137 value["KK"] = LZ(value["K"]); 138 value["kk"] = LZ(value["k"]); 139 if (H > 11) { value["a"] = "PM"; } 140 else { value["a"] = "AM"; } 141 value["m"] = m; 142 value["mm"] = LZ(m); 143 value["s"] = s; 144 value["ss"] = LZ(s); 145 while (i_format < format.length) { 146 c = format.charAt(i_format); 147 token = ""; 148 while ((format.charAt(i_format) == c) && (i_format < format.length)) { 149 token += format.charAt(i_format++); 150 } 151 if (value[token] != null) { result = result + value[token]; } 152 else { result = result + token; } 153 } 154 return result; 155} 156 157// ------------------------------------------------------------------ 158// Utility functions for parsing in getDateFromFormat() 159// ------------------------------------------------------------------ 160function _isInteger(val) { 161 var digits = "1234567890"; 162 for (var i = 0; i < val.length; i++) { 163 if (digits.indexOf(val.charAt(i)) == -1) { return false; } 164 } 165 return true; 166} 167function _getInt(str, i, minlength, maxlength) { 168 for (var x = maxlength; x >= minlength; x--) { 169 var token = str.substring(i, i + x); 170 if (token.length < minlength) { return null; } 171 if (_isInteger(token)) { return token; } 172 } 173 return null; 174} 175 176// ------------------------------------------------------------------ 177// getDateFromFormat( date_string , format_string ) 178// 179// This function takes a date string and a format string. It matches 180// If the date string matches the format string, it returns the 181// getTime() of the date. If it does not match, it returns 0. 182// ------------------------------------------------------------------ 183function getDateFromFormat(val, format) { 184 val = val + ""; 185 format = format + ""; 186 var i_val = 0; 187 var i_format = 0; 188 var c = ""; 189 var token = ""; 190 var token2 = ""; 191 var x, y; 192 var now = new Date(); 193 var year = now.getYear(); 194 var month = now.getMonth() + 1; 195 var date = 1; 196 var hh = now.getHours(); 197 var mm = now.getMinutes(); 198 var ss = now.getSeconds(); 199 var ampm = ""; 200 201 while (i_format < format.length) {
202 // Get next token from format string 203 c = format.charAt(i_format); 204 token = ""; 205 while ((format.charAt(i_format) == c) && (i_format < format.length)) { 206 token += format.charAt(i_format++); 207 } 208 // Extract contents of value based on format token 209 if (token == "yyyy" || token == "yy" || token == "y") { 210 if (token == "yyyy") { x = 4; y = 4; } 211 if (token == "yy") { x = 2; y = 2; } 212 if (token == "y") { x = 2; y = 4; } 213 year = _getInt(val, i_val, x, y); 214 if (year == null) { return 0; } 215 i_val += year.length; 216 if (year.length == 2) { 217 if (year > 70) { year = 1900 + (year - 0); } 218 else { year = 2000 + (year - 0); } 219 } 220 } 221 else if (token == "MMM" || token == "NNN") { 222 month = 0; 223 for (var i = 0; i < MONTH_NAMES.length; i++) { 224 var month_name = MONTH_NAMES[i]; 225 if (val.substring(i_val, i_val + month_name.length).toLowerCase() == month_name.toLowerCase()) { 226 if (token == "MMM" || (token == "NNN" && i > 11)) { 227 month = i + 1; 228 if (month > 12) { month -= 12; } 229 i_val += month_name.length; 230 break; 231 } 232 } 233 } 234 if ((month < 1) || (month > 12)) { return 0; } 235 } 236 else if (token == "EE" || token == "E") { 237 for (var i = 0; i < DAY_NAMES.length; i++) { 238 var day_name = DAY_NAMES[i]; 239 if (val.substring(i_val, i_val + day_name.length).toLowerCase() == day_name.toLowerCase()) { 240 i_val += day_name.length; 241 break; 242 } 243 } 244 } 245 else if (token == "MM" || token == "M") { 246 month = _getInt(val, i_val, token.length, 2); 247 if (month == null || (month < 1) || (month > 12)) { return 0; } 248 i_val += month.length; 249 } 250 else if (token == "dd" || token == "d") { 251 date = _getInt(val, i_val, token.length, 2); 252 if (date == null || (date < 1) || (date > 31)) { return 0; } 253 i_val += date.length; 254 } 255 else if (token == "hh" || token == "h") { 256 hh = _getInt(val, i_val, token.length, 2); 257 if (hh == null || (hh < 1) || (hh > 12)) { return 0; } 258 i_val += hh.length; 259 } 260 else if (token == "HH" || token == "H") { 261 hh = _getInt(val, i_val, token.length, 2); 262 if (hh == null || (hh < 0) || (hh > 23)) { return 0; } 263 i_val += hh.length; 264 } 265 else if (token == "KK" || token == "K") { 266 hh = _getInt(val, i_val, token.length, 2); 267 if (hh == null || (hh < 0) || (hh > 11)) { return 0; } 268 i_val += hh.length; 269 } 270 else if (token == "kk" || token == "k") { 271 hh = _getInt(val, i_val, token.length, 2); 272 if (hh == null || (hh < 1) || (hh > 24)) { return 0; } 273 i_val += hh.length; hh--; 274 } 275 else if (token == "mm" || token == "m") { 276 mm = _getInt(val, i_val, token.length, 2); 277 if (mm == null || (mm < 0) || (mm > 59)) { return 0; } 278 i_val += mm.length; 279 } 280 else if (token == "ss" || token == "s") { 281 ss = _getInt(val, i_val, token.length, 2); 282 if (ss == null || (ss < 0) || (ss > 59)) { return 0; } 283 i_val += ss.length; 284 } 285 else if (token == "a") { 286 if (val.substring(i_val, i_val + 2).toLowerCase() == "am") { ampm = "AM"; } 287 else if (val.substring(i_val, i_val + 2).toLowerCase() == "pm") { ampm = "PM"; } 288 else { return 0; } 289 i_val += 2; 290 } 291 else { 292 if (val.substring(i_val, i_val + token.length) != token) { return 0; } 293 else { i_val += token.length; } 294 } 295 } 296 // If there are any trailing characters left in the value, it doesn't match 297 if (i_val != val.length) { return 0; } 298 // Is date valid for month? 299 if (month == 2) { 300 // Check for leap year 301 if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) { // leap year 302 if (date > 29) { return 0; } 303 } 304 else { if (date > 28) { return 0; } } 305 } 306 if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) { 307 if (date > 30) { return 0; } 308 } 309 // Correct hours value 310 if (hh < 12 && ampm == "PM") { hh = hh - 0 + 12; } 311 else if (hh > 11 && ampm == "AM") { hh -= 12; } 312 var newdate = new Date(year, month - 1, date, hh, mm, ss); 313 return newdate.getTime(); 314} 315 316// ------------------------------------------------------------------ 317// parseDate( date_string [, prefer_euro_format] ) 318// 319// This function takes a date string and tries to match it to a 320// number of possible date formats to get the value. It will try to 321// match against the following international formats, in this order: 322// y-M-d MMM d, y MMM d,y y-MMM-d d-MMM-y MMM d 323// M/d/y M-d-y M.d.y MMM-d M/d M-d 324// d/M/y d-M-y d.M.y d-MMM d/M d-M 325// A second argument may be passed to instruct the method to search 326// for formats like d/M/y (european format) before M/d/y (American). 327// Returns a Date object or null if no patterns match. 328// ------------------------------------------------------------------ 329function parseDate(val) { 330 var preferEuro = (arguments.length == 2) ? arguments[1] : false; 331 generalFormats = new Array('y-M-d', 'MMM d, y', 'MMM d,y', 'y-MMM-d', 'd-MMM-y', 'MMM d'); 332 monthFirst = new Array('M/d/y', 'M-d-y', 'M.d.y', 'MMM-d', 'M/d', 'M-d'); 333 dateFirst = new Array('d/M/y', 'd-M-y', 'd.M.y', 'd-MMM', 'd/M', 'd-M'); 334 var checkList = new Array('generalFormats', preferEuro ? 'dateFirst' : 'monthFirst', preferEuro ? 'monthFirst' : 'dateFirst'); 335 var d = null; 336 for (var i = 0; i < checkList.length; i++) { 337 var l = window[checkList[i]]; 338 for (var j = 0; j < l.length; j++) { 339 d = getDateFromFormat(val, l[j]); 340 if (d != 0) { return new Date(d); } 341 } 342 } 343 return null; 344}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.