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