Does anyone know of a reg expression for uk date format

后端 未结 7 924
青春惊慌失措
青春惊慌失措 2021-01-18 21:39

Hi does any one know a reg ex for a uk date format e.g. dd/mm/yyyy.

The dd or mm can be 1 character e.g. 1/1/2010 but the year must always be 4 characters.

T

相关标签:
7条回答
  • 2021-01-18 22:31

    There are two things you want to do, which in my view are best considered separately

    1) You want to make sure that the date is a real, actual date. For example the 2019-02-29 isn't a real date whereas 2020-02-29 is a real date because 2020 is a leap year

    2) You want to check that the date is in the correct format (so dd/mm/yyyy)

    The second point can be done easily enough with a simple RegEx, plenty of examples of that.

    To complicate matters, if you ask Firefox if 2019-02-29 is a real date, it'll return NaN, which is what you'd expect.

    Chrome, on the other hand will say it is a real date and give you back the 1st of March 2019 - which will validate

    Chrome, will also accept a single digit number as a proper date too for some strange reason, feed it "2" and it'll give you full date from 2001 back - which will validate

    So first step is to create a function which attempts to decipher a date (no matter the format) and works cross-browser to return a boolean indicating if the date is valid or not

    function validatableDate(value) 
    {
        Date.prototype.isValid = function() 
        {   // An invalid date object returns NaN for getTime() and NaN is the only
            // object not strictly equal to itself.
            return this.getTime() === this.getTime();
        };
        minTwoDigits = function(n) 
        {   //pads any digit less than 10 with a leading 0
            return (parseInt(n) < 10 ? '0' : '') + parseInt(n);
        }
        var valid_date = false;
        var iso_array = null;
        // check if there are date dividers (gets around chrome allowing single digit numbers)
        if ((value.indexOf('/') != -1) || (value.indexOf('-') != -1)) { //if we're dealing with - dividers we'll do some pre-processing and swap them out for /
            if (value.indexOf('-') != -1) {
                dash_parts = value.split('-');
                value = dash_parts.join("/");
                //if we have a leading year, we'll put it at the end and work things out from there
                if (dash_parts[0].length > 2) {
                    value = dash_parts[1] + '/' + dash_parts[2] + '/' + dash_parts[0];
                }
            }
    
            parts = value.split('/');
            if (parts[0] > 12) { //convert to ISO from UK dd/mm/yyyy format
                iso_array = [parts[2], minTwoDigits(parts[1]), minTwoDigits(parts[0])]
            } else if (parts[1] > 12) { //convert to ISO from American mm/dd/yyyy format                                                
                iso_array = [parts[2], minTwoDigits(parts[0]), minTwoDigits(parts[1])]
            } else //if a date is valid in either UK or US (e.g. 12/12/2017 , 10/10/2017) then we don't particularly care what format it is in - it's valid regardless
            {
                iso_array = [parts[2], minTwoDigits(parts[0]), minTwoDigits(parts[1])]
            }
    
            if (Array.isArray(iso_array)) {
                value = iso_array.join("-");
                var d = new Date(value + 'T00:00:01Z');
                if (d.isValid()) //test if it is a valid date (there are issues with this in Chrome with Feb)
                {
                    valid_date = true;
                }
                //if the month is Feb we need to do another step to cope with Chrome peculiarities
                if (parseInt(iso_array[1]) == 2) {
                    month_info = new Date(iso_array[0], iso_array[1], 0);
                    //if the day inputed is larger than the last day of the February in that year
                    if (iso_array[2] > month_info.getDate()) {
                        valid_date = false;
                    }
                }
            }
        }
        return valid_date;
    }
    

    That can be compressed down to

    function validatableDate(t) {
        Date.prototype.isValid = function () {
            return this.getTime() === this.getTime()
        }, minTwoDigits = function (t) {
            return (parseInt(t) < 10 ? "0" : "") + parseInt(t)
        };
        var a = !1,
            i = null;
        return -1 == t.indexOf("/") && -1 == t.indexOf("-") || (-1 != t.indexOf("-") && (dash_parts = t.split("-"), t = dash_parts.join("/"), dash_parts[0].length > 2 && (t = dash_parts[1] + "/" + dash_parts[2] + "/" + dash_parts[0])), parts = t.split("/"), i = parts[0] > 12 ? [parts[2], minTwoDigits(parts[1]), minTwoDigits(parts[0])] : (parts[1], [parts[2], minTwoDigits(parts[0]), minTwoDigits(parts[1])]), Array.isArray(i) && (t = i.join("-"), new Date(t + "T00:00:01Z").isValid() && (a = !0), 2 == parseInt(i[1]) && (month_info = new Date(i[0], i[1], 0), i[2] > month_info.getDate() && (a = !1)))), a
    }
    

    That gets you a cross-browser test as to whether the date can be validated or not and it'll read & decipher dates in formats

    • yyyy-mm-dd
    • dd-mm-yyyy
    • mm-dd-yyyy
    • dd/mm/yyyy
    • mm/dd/yyyy

    Once you've validated the date is a real, proper one you can then test the format with a regex. So for UK dd/mm/yy

    function dateUK(value) {
        valid_uk_date=false;
        valid_date=validatableDate(value);
        if(valid_date && value.match(/^(0?[1-9]|[12][0-9]|3[01])[\/](0?[1-9]|1[012])[\/]\d{4}$/))
        {   valid_uk_date=true;
        }
        return  valid_uk_date;              
    }
    

    You then know that the date is a real one and that it's in the correct format.

    For yyyy-mm-dd format, you'd do:

    function dateISO(value) {
        valid_iso_date=false;
        valid_date=validatableDate(value);
        if(valid_date && value.match(/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/))
        {   valid_iso_date=true;
        }
        return  valid_iso_date;             
    }
    

    It depends how thorough you want to be of course, for a rough check of format sanity a RegEx may be enough for your purposes. If however you want to test if the date is a real one AND if the format is valid then this will hopefully help point you along the way

    Thanks

    0 讨论(0)
提交回复
热议问题