tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

check-date-format-xparb.js (12283B)


      1 /*
      2 * Copyright (C) 2004 Baron Schwartz <baron at sequent dot org>
      3 *
      4 * This program is free software; you can redistribute it and/or modify it
      5 * under the terms of the GNU Lesser General Public License as published by the
      6 * Free Software Foundation, version 2.1.
      7 *
      8 * This program is distributed in the hope that it will be useful, but WITHOUT
      9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
     10 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
     11 * details.
     12 */
     13 
     14 Date.parseFunctions = {count:0};
     15 Date.parseRegexes = [];
     16 Date.formatFunctions = {count:0};
     17 
     18 Date.prototype.dateFormat = function(format) {
     19    if (Date.formatFunctions[format] == null) {
     20        Date.createNewFormat(format);
     21    }
     22    var func = Date.formatFunctions[format];
     23    return this[func]();
     24 }
     25 
     26 Date.createNewFormat = function(format) {
     27    var funcName = "format" + Date.formatFunctions.count++;
     28    Date.formatFunctions[format] = funcName;
     29    var code = "Date.prototype." + funcName + " = function(){return ";
     30    var special = false;
     31    var ch = '';
     32    for (var i = 0; i < format.length; ++i) {
     33        ch = format.charAt(i);
     34        if (!special && ch == "\\") {
     35            special = true;
     36        }
     37        else if (special) {
     38            special = false;
     39            code += "'" + String.escape(ch) + "' + ";
     40        }
     41        else {
     42            code += Date.getFormatCode(ch);
     43        }
     44    }
     45    eval(code.substring(0, code.length - 3) + ";}");
     46 }
     47 
     48 Date.getFormatCode = function(character) {
     49    switch (character) {
     50    case "d":
     51        return "String.leftPad(this.getDate(), 2, '0') + ";
     52    case "D":
     53        return "Date.dayNames[this.getDay()].substring(0, 3) + ";
     54    case "j":
     55        return "this.getDate() + ";
     56    case "l":
     57        return "Date.dayNames[this.getDay()] + ";
     58    case "S":
     59        return "this.getSuffix() + ";
     60    case "w":
     61        return "this.getDay() + ";
     62    case "z":
     63        return "this.getDayOfYear() + ";
     64    case "W":
     65        return "this.getWeekOfYear() + ";
     66    case "F":
     67        return "Date.monthNames[this.getMonth()] + ";
     68    case "m":
     69        return "String.leftPad(this.getMonth() + 1, 2, '0') + ";
     70    case "M":
     71        return "Date.monthNames[this.getMonth()].substring(0, 3) + ";
     72    case "n":
     73        return "(this.getMonth() + 1) + ";
     74    case "t":
     75        return "this.getDaysInMonth() + ";
     76    case "L":
     77        return "(this.isLeapYear() ? 1 : 0) + ";
     78    case "Y":
     79        return "this.getFullYear() + ";
     80    case "y":
     81        return "('' + this.getFullYear()).substring(2, 4) + ";
     82    case "a":
     83        return "(this.getHours() < 12 ? 'am' : 'pm') + ";
     84    case "A":
     85        return "(this.getHours() < 12 ? 'AM' : 'PM') + ";
     86    case "g":
     87        return "((this.getHours() %12) ? this.getHours() % 12 : 12) + ";
     88    case "G":
     89        return "this.getHours() + ";
     90    case "h":
     91        return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + ";
     92    case "H":
     93        return "String.leftPad(this.getHours(), 2, '0') + ";
     94    case "i":
     95        return "String.leftPad(this.getMinutes(), 2, '0') + ";
     96    case "s":
     97        return "String.leftPad(this.getSeconds(), 2, '0') + ";
     98    case "O":
     99        return "this.getGMTOffset() + ";
    100    case "T":
    101        return "this.getTimezone() + ";
    102    case "Z":
    103        return "(this.getTimezoneOffset() * -60) + ";
    104    default:
    105        return "'" + String.escape(character) + "' + ";
    106    }
    107 }
    108 
    109 Date.parseDate = function(input, format) {
    110    if (Date.parseFunctions[format] == null) {
    111        Date.createParser(format);
    112    }
    113    var func = Date.parseFunctions[format];
    114    return Date[func](input);
    115 }
    116 
    117 Date.createParser = function(format) {
    118    var funcName = "parse" + Date.parseFunctions.count++;
    119    var regexNum = Date.parseRegexes.length;
    120    var currentGroup = 1;
    121    Date.parseFunctions[format] = funcName;
    122 
    123    var code = "Date." + funcName + " = function(input){\n"
    124        + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1;\n"
    125        + "var d = new Date();\n"
    126        + "y = d.getFullYear();\n"
    127        + "m = d.getMonth();\n"
    128        + "d = d.getDate();\n"
    129        + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
    130        + "if (results && results.length > 0) {"
    131    var regex = "";
    132 
    133    var special = false;
    134    var ch = '';
    135    for (var i = 0; i < format.length; ++i) {
    136        ch = format.charAt(i);
    137        if (!special && ch == "\\") {
    138            special = true;
    139        }
    140        else if (special) {
    141            special = false;
    142            regex += String.escape(ch);
    143        }
    144        else {
    145            obj = Date.formatCodeToRegex(ch, currentGroup);
    146            currentGroup += obj.g;
    147            regex += obj.s;
    148            if (obj.g && obj.c) {
    149                code += obj.c;
    150            }
    151        }
    152    }
    153 
    154    code += "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"
    155        + "{return new Date(y, m, d, h, i, s);}\n"
    156        + "else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"
    157        + "{return new Date(y, m, d, h, i);}\n"
    158        + "else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n"
    159        + "{return new Date(y, m, d, h);}\n"
    160        + "else if (y > 0 && m >= 0 && d > 0)\n"
    161        + "{return new Date(y, m, d);}\n"
    162        + "else if (y > 0 && m >= 0)\n"
    163        + "{return new Date(y, m);}\n"
    164        + "else if (y > 0)\n"
    165        + "{return new Date(y);}\n"
    166        + "}return null;}";
    167 
    168    Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$");
    169    eval(code);
    170 }
    171 
    172 Date.formatCodeToRegex = function(character, currentGroup) {
    173    switch (character) {
    174    case "D":
    175        return {g:0,
    176        c:null,
    177        s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"};
    178    case "j":
    179    case "d":
    180        return {g:1,
    181            c:"d = parseInt(results[" + currentGroup + "], 10);\n",
    182            s:"(\\d{1,2})"};
    183    case "l":
    184        return {g:0,
    185            c:null,
    186            s:"(?:" + Date.dayNames.join("|") + ")"};
    187    case "S":
    188        return {g:0,
    189            c:null,
    190            s:"(?:st|nd|rd|th)"};
    191    case "w":
    192        return {g:0,
    193            c:null,
    194            s:"\\d"};
    195    case "z":
    196        return {g:0,
    197            c:null,
    198            s:"(?:\\d{1,3})"};
    199    case "W":
    200        return {g:0,
    201            c:null,
    202            s:"(?:\\d{2})"};
    203    case "F":
    204        return {g:1,
    205            c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "].substring(0, 3)], 10);\n",
    206            s:"(" + Date.monthNames.join("|") + ")"};
    207    case "M":
    208        return {g:1,
    209            c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "]], 10);\n",
    210            s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"};
    211    case "n":
    212    case "m":
    213        return {g:1,
    214            c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
    215            s:"(\\d{1,2})"};
    216    case "t":
    217        return {g:0,
    218            c:null,
    219            s:"\\d{1,2}"};
    220    case "L":
    221        return {g:0,
    222            c:null,
    223            s:"(?:1|0)"};
    224    case "Y":
    225        return {g:1,
    226            c:"y = parseInt(results[" + currentGroup + "], 10);\n",
    227            s:"(\\d{4})"};
    228    case "y":
    229        return {g:1,
    230            c:"var ty = parseInt(results[" + currentGroup + "], 10);\n"
    231                + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
    232            s:"(\\d{1,2})"};
    233    case "a":
    234        return {g:1,
    235            c:"if (results[" + currentGroup + "] == 'am') {\n"
    236                + "if (h == 12) { h = 0; }\n"
    237                + "} else { if (h < 12) { h += 12; }}",
    238            s:"(am|pm)"};
    239    case "A":
    240        return {g:1,
    241            c:"if (results[" + currentGroup + "] == 'AM') {\n"
    242                + "if (h == 12) { h = 0; }\n"
    243                + "} else { if (h < 12) { h += 12; }}",
    244            s:"(AM|PM)"};
    245    case "g":
    246    case "G":
    247    case "h":
    248    case "H":
    249        return {g:1,
    250            c:"h = parseInt(results[" + currentGroup + "], 10);\n",
    251            s:"(\\d{1,2})"};
    252    case "i":
    253        return {g:1,
    254            c:"i = parseInt(results[" + currentGroup + "], 10);\n",
    255            s:"(\\d{2})"};
    256    case "s":
    257        return {g:1,
    258            c:"s = parseInt(results[" + currentGroup + "], 10);\n",
    259            s:"(\\d{2})"};
    260    case "O":
    261        return {g:0,
    262            c:null,
    263            s:"[+-]\\d{4}"};
    264    case "T":
    265        return {g:0,
    266            c:null,
    267            s:"[A-Z]{3}"};
    268    case "Z":
    269        return {g:0,
    270            c:null,
    271            s:"[+-]\\d{1,5}"};
    272    default:
    273        return {g:0,
    274            c:null,
    275            s:String.escape(character)};
    276    }
    277 }
    278 
    279 Date.prototype.getTimezone = function() {
    280    return this.toString().replace(
    281        /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace(
    282        /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3");
    283 }
    284 
    285 Date.prototype.getGMTOffset = function() {
    286    return (this.getTimezoneOffset() > 0 ? "-" : "+")
    287        + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0")
    288        + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
    289 }
    290 
    291 Date.prototype.getDayOfYear = function() {
    292    var num = 0;
    293    Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
    294    for (var i = 0; i < this.getMonth(); ++i) {
    295        num += Date.daysInMonth[i];
    296    }
    297    return num + this.getDate() - 1;
    298 }
    299 
    300 Date.prototype.getWeekOfYear = function() {
    301    // Skip to Thursday of this week
    302    var now = this.getDayOfYear() + (4 - this.getDay());
    303    // Find the first Thursday of the year
    304    var jan1 = new Date(this.getFullYear(), 0, 1);
    305    var then = (7 - jan1.getDay() + 4);
    306    document.write(then);
    307    return String.leftPad(((now - then) / 7) + 1, 2, "0");
    308 }
    309 
    310 Date.prototype.isLeapYear = function() {
    311    var year = this.getFullYear();
    312    return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
    313 }
    314 
    315 Date.prototype.getFirstDayOfMonth = function() {
    316    var day = (this.getDay() - (this.getDate() - 1)) % 7;
    317    return (day < 0) ? (day + 7) : day;
    318 }
    319 
    320 Date.prototype.getLastDayOfMonth = function() {
    321    var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
    322    return (day < 0) ? (day + 7) : day;
    323 }
    324 
    325 Date.prototype.getDaysInMonth = function() {
    326    Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
    327    return Date.daysInMonth[this.getMonth()];
    328 }
    329 
    330 Date.prototype.getSuffix = function() {
    331    switch (this.getDate()) {
    332        case 1:
    333        case 21:
    334        case 31:
    335            return "st";
    336        case 2:
    337        case 22:
    338            return "nd";
    339        case 3:
    340        case 23:
    341            return "rd";
    342        default:
    343            return "th";
    344    }
    345 }
    346 
    347 String.escape = function(string) {
    348    return string.replace(/('|\\)/g, "\\$1");
    349 }
    350 
    351 String.leftPad = function (val, size, ch) {
    352    var result = new String(val);
    353    if (ch == null) {
    354        ch = " ";
    355    }
    356    while (result.length < size) {
    357        result = ch + result;
    358    }
    359    return result;
    360 }
    361 
    362 Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
    363 Date.monthNames =
    364   ["January",
    365    "February",
    366    "March",
    367    "April",
    368    "May",
    369    "June",
    370    "July",
    371    "August",
    372    "September",
    373    "October",
    374    "November",
    375    "December"];
    376 Date.dayNames =
    377   ["Sunday",
    378    "Monday",
    379    "Tuesday",
    380    "Wednesday",
    381    "Thursday",
    382    "Friday",
    383    "Saturday"];
    384 Date.y2kYear = 50;
    385 Date.monthNumbers = {
    386    Jan:0,
    387    Feb:1,
    388    Mar:2,
    389    Apr:3,
    390    May:4,
    391    Jun:5,
    392    Jul:6,
    393    Aug:7,
    394    Sep:8,
    395    Oct:9,
    396    Nov:10,
    397    Dec:11};
    398 Date.patterns = {
    399    ISO8601LongPattern:"Y-m-d H:i:s",
    400    ISO8601ShortPattern:"Y-m-d",
    401    ShortDatePattern: "n/j/Y",
    402    LongDatePattern: "l, F d, Y",
    403    FullDateTimePattern: "l, F d, Y g:i:s A",
    404    MonthDayPattern: "F d",
    405    ShortTimePattern: "g:i A",
    406    LongTimePattern: "g:i:s A",
    407    SortableDateTimePattern: "Y-m-d\\TH:i:s",
    408    UniversalSortableDateTimePattern: "Y-m-d H:i:sO",
    409    YearMonthPattern: "F, Y"};
    410 
    411 var date = new Date("1/1/2007 1:11:11");
    412 
    413 var ret;
    414 for (i = 0; i < 4000; ++i) {
    415    var shortFormat = date.dateFormat("Y-m-d");
    416    var longFormat = date.dateFormat("l, F d, Y g:i:s A");
    417    ret = shortFormat + longFormat;
    418    date.setTime(date.getTime() + 84266956);
    419 }
    420 
    421 // No exact match because the output depends on the locale's time zone. See bug 524490.
    422 assertEq(/^2017-09-05Tuesday, September 05, 2017 [0-9:]* AM$/.exec(ret) != null, true);