annotate media/django/js/dateparse.js @ 1:0dcfcdf50c62

Initial import of Madeira project from the private repository.
author Brian Neal <bgneal@gmail.com>
date Mon, 06 Apr 2009 03:10:59 +0000
parents
children
rev   line source
bgneal@1 1 /* 'Magic' date parsing, by Simon Willison (6th October 2003)
bgneal@1 2 http://simon.incutio.com/archive/2003/10/06/betterDateInput
bgneal@1 3 Adapted for 6newslawrence.com, 28th January 2004
bgneal@1 4 */
bgneal@1 5
bgneal@1 6 /* Finds the index of the first occurence of item in the array, or -1 if not found */
bgneal@1 7 if (typeof Array.prototype.indexOf == 'undefined') {
bgneal@1 8 Array.prototype.indexOf = function(item) {
bgneal@1 9 var len = this.length;
bgneal@1 10 for (var i = 0; i < len; i++) {
bgneal@1 11 if (this[i] == item) {
bgneal@1 12 return i;
bgneal@1 13 }
bgneal@1 14 }
bgneal@1 15 return -1;
bgneal@1 16 };
bgneal@1 17 }
bgneal@1 18 /* Returns an array of items judged 'true' by the passed in test function */
bgneal@1 19 if (typeof Array.prototype.filter == 'undefined') {
bgneal@1 20 Array.prototype.filter = function(test) {
bgneal@1 21 var matches = [];
bgneal@1 22 var len = this.length;
bgneal@1 23 for (var i = 0; i < len; i++) {
bgneal@1 24 if (test(this[i])) {
bgneal@1 25 matches[matches.length] = this[i];
bgneal@1 26 }
bgneal@1 27 }
bgneal@1 28 return matches;
bgneal@1 29 };
bgneal@1 30 }
bgneal@1 31
bgneal@1 32 var monthNames = gettext("January February March April May June July August September October November December").split(" ");
bgneal@1 33 var weekdayNames = gettext("Sunday Monday Tuesday Wednesday Thursday Friday Saturday").split(" ");
bgneal@1 34
bgneal@1 35 /* Takes a string, returns the index of the month matching that string, throws
bgneal@1 36 an error if 0 or more than 1 matches
bgneal@1 37 */
bgneal@1 38 function parseMonth(month) {
bgneal@1 39 var matches = monthNames.filter(function(item) {
bgneal@1 40 return new RegExp("^" + month, "i").test(item);
bgneal@1 41 });
bgneal@1 42 if (matches.length == 0) {
bgneal@1 43 throw new Error("Invalid month string");
bgneal@1 44 }
bgneal@1 45 if (matches.length > 1) {
bgneal@1 46 throw new Error("Ambiguous month");
bgneal@1 47 }
bgneal@1 48 return monthNames.indexOf(matches[0]);
bgneal@1 49 }
bgneal@1 50 /* Same as parseMonth but for days of the week */
bgneal@1 51 function parseWeekday(weekday) {
bgneal@1 52 var matches = weekdayNames.filter(function(item) {
bgneal@1 53 return new RegExp("^" + weekday, "i").test(item);
bgneal@1 54 });
bgneal@1 55 if (matches.length == 0) {
bgneal@1 56 throw new Error("Invalid day string");
bgneal@1 57 }
bgneal@1 58 if (matches.length > 1) {
bgneal@1 59 throw new Error("Ambiguous weekday");
bgneal@1 60 }
bgneal@1 61 return weekdayNames.indexOf(matches[0]);
bgneal@1 62 }
bgneal@1 63
bgneal@1 64 /* Array of objects, each has 're', a regular expression and 'handler', a
bgneal@1 65 function for creating a date from something that matches the regular
bgneal@1 66 expression. Handlers may throw errors if string is unparseable.
bgneal@1 67 */
bgneal@1 68 var dateParsePatterns = [
bgneal@1 69 // Today
bgneal@1 70 { re: /^tod/i,
bgneal@1 71 handler: function() {
bgneal@1 72 return new Date();
bgneal@1 73 }
bgneal@1 74 },
bgneal@1 75 // Tomorrow
bgneal@1 76 { re: /^tom/i,
bgneal@1 77 handler: function() {
bgneal@1 78 var d = new Date();
bgneal@1 79 d.setDate(d.getDate() + 1);
bgneal@1 80 return d;
bgneal@1 81 }
bgneal@1 82 },
bgneal@1 83 // Yesterday
bgneal@1 84 { re: /^yes/i,
bgneal@1 85 handler: function() {
bgneal@1 86 var d = new Date();
bgneal@1 87 d.setDate(d.getDate() - 1);
bgneal@1 88 return d;
bgneal@1 89 }
bgneal@1 90 },
bgneal@1 91 // 4th
bgneal@1 92 { re: /^(\d{1,2})(st|nd|rd|th)?$/i,
bgneal@1 93 handler: function(bits) {
bgneal@1 94 var d = new Date();
bgneal@1 95 d.setDate(parseInt(bits[1], 10));
bgneal@1 96 return d;
bgneal@1 97 }
bgneal@1 98 },
bgneal@1 99 // 4th Jan
bgneal@1 100 { re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+)$/i,
bgneal@1 101 handler: function(bits) {
bgneal@1 102 var d = new Date();
bgneal@1 103 d.setDate(parseInt(bits[1], 10));
bgneal@1 104 d.setMonth(parseMonth(bits[2]));
bgneal@1 105 return d;
bgneal@1 106 }
bgneal@1 107 },
bgneal@1 108 // 4th Jan 2003
bgneal@1 109 { re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+),? (\d{4})$/i,
bgneal@1 110 handler: function(bits) {
bgneal@1 111 var d = new Date();
bgneal@1 112 d.setDate(parseInt(bits[1], 10));
bgneal@1 113 d.setMonth(parseMonth(bits[2]));
bgneal@1 114 d.setYear(bits[3]);
bgneal@1 115 return d;
bgneal@1 116 }
bgneal@1 117 },
bgneal@1 118 // Jan 4th
bgneal@1 119 { re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?$/i,
bgneal@1 120 handler: function(bits) {
bgneal@1 121 var d = new Date();
bgneal@1 122 d.setDate(parseInt(bits[2], 10));
bgneal@1 123 d.setMonth(parseMonth(bits[1]));
bgneal@1 124 return d;
bgneal@1 125 }
bgneal@1 126 },
bgneal@1 127 // Jan 4th 2003
bgneal@1 128 { re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?,? (\d{4})$/i,
bgneal@1 129 handler: function(bits) {
bgneal@1 130 var d = new Date();
bgneal@1 131 d.setDate(parseInt(bits[2], 10));
bgneal@1 132 d.setMonth(parseMonth(bits[1]));
bgneal@1 133 d.setYear(bits[3]);
bgneal@1 134 return d;
bgneal@1 135 }
bgneal@1 136 },
bgneal@1 137 // next Tuesday - this is suspect due to weird meaning of "next"
bgneal@1 138 { re: /^next (\w+)$/i,
bgneal@1 139 handler: function(bits) {
bgneal@1 140 var d = new Date();
bgneal@1 141 var day = d.getDay();
bgneal@1 142 var newDay = parseWeekday(bits[1]);
bgneal@1 143 var addDays = newDay - day;
bgneal@1 144 if (newDay <= day) {
bgneal@1 145 addDays += 7;
bgneal@1 146 }
bgneal@1 147 d.setDate(d.getDate() + addDays);
bgneal@1 148 return d;
bgneal@1 149 }
bgneal@1 150 },
bgneal@1 151 // last Tuesday
bgneal@1 152 { re: /^last (\w+)$/i,
bgneal@1 153 handler: function(bits) {
bgneal@1 154 throw new Error("Not yet implemented");
bgneal@1 155 }
bgneal@1 156 },
bgneal@1 157 // mm/dd/yyyy (American style)
bgneal@1 158 { re: /(\d{1,2})\/(\d{1,2})\/(\d{4})/,
bgneal@1 159 handler: function(bits) {
bgneal@1 160 var d = new Date();
bgneal@1 161 d.setYear(bits[3]);
bgneal@1 162 d.setDate(parseInt(bits[2], 10));
bgneal@1 163 d.setMonth(parseInt(bits[1], 10) - 1); // Because months indexed from 0
bgneal@1 164 return d;
bgneal@1 165 }
bgneal@1 166 },
bgneal@1 167 // yyyy-mm-dd (ISO style)
bgneal@1 168 { re: /(\d{4})-(\d{1,2})-(\d{1,2})/,
bgneal@1 169 handler: function(bits) {
bgneal@1 170 var d = new Date();
bgneal@1 171 d.setYear(parseInt(bits[1]));
bgneal@1 172 d.setMonth(parseInt(bits[2], 10) - 1);
bgneal@1 173 d.setDate(parseInt(bits[3], 10));
bgneal@1 174 return d;
bgneal@1 175 }
bgneal@1 176 },
bgneal@1 177 ];
bgneal@1 178
bgneal@1 179 function parseDateString(s) {
bgneal@1 180 for (var i = 0; i < dateParsePatterns.length; i++) {
bgneal@1 181 var re = dateParsePatterns[i].re;
bgneal@1 182 var handler = dateParsePatterns[i].handler;
bgneal@1 183 var bits = re.exec(s);
bgneal@1 184 if (bits) {
bgneal@1 185 return handler(bits);
bgneal@1 186 }
bgneal@1 187 }
bgneal@1 188 throw new Error("Invalid date string");
bgneal@1 189 }
bgneal@1 190
bgneal@1 191 function fmt00(x) {
bgneal@1 192 // fmt00: Tags leading zero onto numbers 0 - 9.
bgneal@1 193 // Particularly useful for displaying results from Date methods.
bgneal@1 194 //
bgneal@1 195 if (Math.abs(parseInt(x)) < 10){
bgneal@1 196 x = "0"+ Math.abs(x);
bgneal@1 197 }
bgneal@1 198 return x;
bgneal@1 199 }
bgneal@1 200
bgneal@1 201 function parseDateStringISO(s) {
bgneal@1 202 try {
bgneal@1 203 var d = parseDateString(s);
bgneal@1 204 return d.getFullYear() + '-' + (fmt00(d.getMonth() + 1)) + '-' + fmt00(d.getDate())
bgneal@1 205 }
bgneal@1 206 catch (e) { return s; }
bgneal@1 207 }
bgneal@1 208 function magicDate(input) {
bgneal@1 209 var messagespan = input.id + 'Msg';
bgneal@1 210 try {
bgneal@1 211 var d = parseDateString(input.value);
bgneal@1 212 input.value = d.getFullYear() + '-' + (fmt00(d.getMonth() + 1)) + '-' +
bgneal@1 213 fmt00(d.getDate());
bgneal@1 214 input.className = '';
bgneal@1 215 // Human readable date
bgneal@1 216 if (document.getElementById(messagespan)) {
bgneal@1 217 document.getElementById(messagespan).firstChild.nodeValue = d.toDateString();
bgneal@1 218 document.getElementById(messagespan).className = 'normal';
bgneal@1 219 }
bgneal@1 220 }
bgneal@1 221 catch (e) {
bgneal@1 222 input.className = 'error';
bgneal@1 223 var message = e.message;
bgneal@1 224 // Fix for IE6 bug
bgneal@1 225 if (message.indexOf('is null or not an object') > -1) {
bgneal@1 226 message = 'Invalid date string';
bgneal@1 227 }
bgneal@1 228 if (document.getElementById(messagespan)) {
bgneal@1 229 document.getElementById(messagespan).firstChild.nodeValue = message;
bgneal@1 230 document.getElementById(messagespan).className = 'error';
bgneal@1 231 }
bgneal@1 232 }
bgneal@1 233 }