JavaScript - 用正则表达式验证日期格式

32

有没有办法通过JavaScript正则表达式验证多种格式的日期,例如:DD-MM-YYYY,DD.MM.YYYY或DD/MM/YYYY等?我需要这些都包含在一个正则表达式中,但我不太擅长。到目前为止,我想到的是:var dateReg = /^\d{2}-\d{2}-\d{4}$/; 用于验证DD-MM-YYYY格式的日期。我只需要验证日期格式,而不是日期本身。


1
你可能会对http://www.datejs.com/感兴趣。 - Py.
如果唯一变化的是分隔符,则将“-”替换为“[-/.]”(或任何需要转义的字符)。 - Dave Newton
请考虑重新分配正确的答案。当前答案匹配不正确的日期(99-99-9999等)。谢谢! - Dropout
@Dropout 我已经编辑了问题,明确说明我只需要验证格式,而不是实际的日期有效性。如果那样的话,@nicoabie 的答案会更好,尽管它声称 01.01-2015 是有效的,所以没有一个回答完全正确地验证了日期。不过还是谢谢你指出这一点。 - Eduard Luca
1
@EduardLuca 好的,非常感谢!只是想让问题后来者更容易理解,希望能有所帮助;) 干杯! - Dropout
显示剩余2条评论
11个回答

45

您可以使用字符类 ([./-]),这样分隔符可以是定义的任何字符。

var dateReg = /^\d{2}[./-]\d{2}[./-]\d{4}$/

或者更好的方法是,匹配第一个分隔符的字符类,然后将其作为一组捕获([./-])并使用对捕获组的引用\1来匹配第二个分隔符,这将确保两个分隔符相同:

var dateReg = /^\d{2}([./-])\d{2}\1\d{4}$/

"22-03-1981".match(dateReg) // matches
"22.03-1981".match(dateReg) // does not match
"22.03.1981".match(dateReg) // matches

1
除了斜杠“/”没有被正确转义之外,它运行良好。谢谢。 - Eduard Luca
我认为在字符类中斜杠不需要转义,但如果你想的话转义也没有坏处。这样做可能会使文本编辑器中的语法高亮效果更好,但无论如何都应该能正常工作。 - Billy Moon
你能否添加一个限制,使得第一个数字(月份)不超过“3”? - vsync
尝试使用 var dateReg = /^0[123]([./-])\d{2}\1\d{4}$/ - Billy Moon
或者您可以使用https://www.npmjs.com/package/raysk-vali进行日期验证等操作。 - Ravi Singh

21

日期格式、天数、月份和年份:

var regex = /^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/;


这部分验证了日期,但仍允许像“30-02-2013”这样无效的日期存在。需要更复杂的规则来考虑不同月份的长度。 - Billy Moon
3
技术上说,@BillyMoon,我们实际上是验证它的格式,而不是日期本身。您的格式允许像2013年02月30日这样的日期,我的朋友。 - nicoabie
是的,我的设计旨在从有效日期中提取数字,而不尝试进行验证,而你的则进行了验证。我认为通过一些调整,您可以对日期进行合理的验证,我很想看到您这样做,但是只有半个验证对我来说就像在悬崖边上有一个脆弱的栏杆,最好干脆不要有任何栏杆,以免有人靠在上面!更好的办法是有一个坚固的栏杆。 - Billy Moon
@BillyMoon 你在说什么格式、天数、月份和年份? - Dropout
@Dropout - 你的问题是针对 @nicoabie 的吗? - Billy Moon
@BillyMoon 哦,抱歉我以为你在说 MM-DD-YYYY 是无效的格式,现在我注意到是2月30日。我的错,对不起。 - Dropout

13

建议的正则表达式只能验证模式,无法验证日期。

因此,99.99.9999将通过正则表达式。

您后来指定了只需要验证模式,但我仍认为创建日期对象更有用。

const isDDMMYYYY = str => {
  let [dd, mm, yyyy] = str.split(/[\.\-\/]/); // change to suit your locale
  dd = +dd;     // cast to number
  yyyy = +yyyy; // cast to number
  let mm0 = mm - 1, // js months are 0 based
    date = new Date(yyyy, mm0, dd, 15, 0, 0, 0); // normalise
  return mm0 === date.getMonth() && dd === date.getDate() && yyyy === date.getFullYear();
};
const dates = [
  "13-01-2023",
  "13.01.2023",
  "13/01/2023",
  "08-08-1991",
  "29/02/2011"
];

dates.forEach(date => console.log(date, ':', isDDMMYYYY(date)));


无效日期值的验证将由我手动完成。如果我输入像08-08-1991这样的内容,使用你的解决方案在JavaScript中会出现“无效日期”的错误。 - Eduard Luca
1
不在Fx:我已将该日期添加到http://jsfiddle.net/mplungjan/Mqh8D/。 你用的是什么浏览器? - mplungjan
如果您使用parseInt函数,务必使用十进制(radix 10),因为08和09是无效的八进制数字。 - mplungjan
为什么要增加和减少月份?请参见:var date = new Date(yyyy,mm-1,dd,0,0,0,0); ((date.getMonth()+1)) - Ndrslmpk
JavaScript的月份是基于0的 - 我可以在构造函数中减少月份或在比较中增加。 - mplungjan

10

您可以使用正则表达式并结合 OR(|)运算符。

function validateDate(date){
    var regex=new RegExp("([0-9]{4}[-](0[1-9]|1[0-2])[-]([0-2]{1}[0-9]{1}|3[0-1]{1})|([0-2]{1}[0-9]{1}|3[0-1]{1})[-](0[1-9]|1[0-2])[-][0-9]{4})");
    var dateOk=regex.test(date);
    if(dateOk){
        alert("Ok");
    }else{
        alert("not Ok");
    }
}

上述函数可以验证YYYY-MM-DD,DD-MM-YYYY日期格式。您可以简单地扩展正则表达式以验证任何日期格式。假设您想要验证YYYY/MM/DD,则只需将“[-]”替换为“[-|/]”。此表达式可以验证日期到31日,月份到12个月。但闰年和以30天结束的月份未经验证。

5

我会给你点赞,因为你提供了一个更简洁的版本。 - m.edmondson

1
请查看以下代码,它可以使任何提供的格式或基于用户语言环境来验证开始/结束日期的日期有效性。可能有更好的方法,但是我已经想出了这个方法。已测试过格式,如:MM/dd/yyyy、dd/MM/yyyy、yyyy-MM-dd、yyyy.MM.dd、yyyy/MM/dd和dd-MM-yyyy。 请注意,提供的日期格式和日期字符串必须匹配。
    <script type="text/javascript">
function validate(format) {

    if(isAfterCurrentDate(document.getElementById('start').value, format)) {
        alert('Date is after the current date.');
    } else {
        alert('Date is not after the current date.');
    }
    if(isBeforeCurrentDate(document.getElementById('start').value, format)) {
        alert('Date is before current date.');
    } else {
        alert('Date is not before current date.');
    }
    if(isCurrentDate(document.getElementById('start').value, format)) {
        alert('Date is current date.');
    } else {
        alert('Date is not a current date.');
    }
    if (isBefore(document.getElementById('start').value, document.getElementById('end').value, format)) {
        alert('Start/Effective Date cannot be greater than End/Expiration Date');
    } else {
        alert('Valid dates...');
    }
    if (isAfter(document.getElementById('start').value, document.getElementById('end').value, format)) {
        alert('End/Expiration Date cannot be less than Start/Effective Date');
    } else {
        alert('Valid dates...');
    }
    if (isEquals(document.getElementById('start').value, document.getElementById('end').value, format)) {
        alert('Dates are equals...');
    } else {
        alert('Dates are not equals...');
    }
    if (isDate(document.getElementById('start').value, format)) {
        alert('Is valid date...');
    } else {
        alert('Is invalid date...');
    }
}

/**
 * This method gets the year index from the supplied format
 */
function getYearIndex(format) {

    var tokens = splitDateFormat(format);

    if (tokens[0] === 'YYYY'
            || tokens[0] === 'yyyy') {
        return 0;
    } else if (tokens[1]=== 'YYYY'
            || tokens[1] === 'yyyy') {
        return 1;
    } else if (tokens[2] === 'YYYY'
            || tokens[2] === 'yyyy') {
        return 2;
    }
    // Returning the default value as -1
    return -1;
}

/**
 * This method returns the year string located at the supplied index
 */
function getYear(date, index) {

    var tokens = splitDateFormat(date);
    return tokens[index];
}

/**
 * This method gets the month index from the supplied format
 */
function getMonthIndex(format) {

    var tokens = splitDateFormat(format);

    if (tokens[0] === 'MM'
            || tokens[0] === 'mm') {
        return 0;
    } else if (tokens[1] === 'MM'
            || tokens[1] === 'mm') {
        return 1;
    } else if (tokens[2] === 'MM'
            || tokens[2] === 'mm') {
        return 2;
    }
    // Returning the default value as -1
    return -1;
}

/**
 * This method returns the month string located at the supplied index
 */
function getMonth(date, index) {

    var tokens = splitDateFormat(date);
    return tokens[index];
}

/**
 * This method gets the date index from the supplied format
 */
function getDateIndex(format) {

    var tokens = splitDateFormat(format);

    if (tokens[0] === 'DD'
            || tokens[0] === 'dd') {
        return 0;
    } else if (tokens[1] === 'DD'
            || tokens[1] === 'dd') {
        return 1;
    } else if (tokens[2] === 'DD'
            || tokens[2] === 'dd') {
        return 2;
    }
    // Returning the default value as -1
    return -1;
}

/**
 * This method returns the date string located at the supplied index
 */
function getDate(date, index) {

    var tokens = splitDateFormat(date);
    return tokens[index];
}

/**
 * This method returns true if date1 is before date2 else return false
 */
function isBefore(date1, date2, format) {
    // Validating if date1 date is greater than the date2 date
    if (new Date(getYear(date1, getYearIndex(format)), 
            getMonth(date1, getMonthIndex(format)) - 1, 
            getDate(date1, getDateIndex(format))).getTime()
        > new Date(getYear(date2, getYearIndex(format)), 
            getMonth(date2, getMonthIndex(format)) - 1, 
            getDate(date2, getDateIndex(format))).getTime()) {
        return true;
    } 
    return false;                
}

/**
 * This method returns true if date1 is after date2 else return false
 */
function isAfter(date1, date2, format) {
    // Validating if date2 date is less than the date1 date
    if (new Date(getYear(date2, getYearIndex(format)), 
            getMonth(date2, getMonthIndex(format)) - 1, 
            getDate(date2, getDateIndex(format))).getTime()
        < new Date(getYear(date1, getYearIndex(format)), 
            getMonth(date1, getMonthIndex(format)) - 1, 
            getDate(date1, getDateIndex(format))).getTime()
        ) {
        return true;
    } 
    return false;                
}

/**
 * This method returns true if date1 is equals to date2 else return false
 */
function isEquals(date1, date2, format) {
    // Validating if date1 date is equals to the date2 date
    if (new Date(getYear(date1, getYearIndex(format)), 
            getMonth(date1, getMonthIndex(format)) - 1, 
            getDate(date1, getDateIndex(format))).getTime()
        === new Date(getYear(date2, getYearIndex(format)), 
            getMonth(date2, getMonthIndex(format)) - 1, 
            getDate(date2, getDateIndex(format))).getTime()) {
        return true;
    } 
    return false;
}

/**
 * This method validates and returns true if the supplied date is 
 * equals to the current date.
 */
function isCurrentDate(date, format) {
    // Validating if the supplied date is the current date
    if (new Date(getYear(date, getYearIndex(format)), 
            getMonth(date, getMonthIndex(format)) - 1, 
            getDate(date, getDateIndex(format))).getTime()
        === new Date(new Date().getFullYear(), 
                new Date().getMonth(), 
                new Date().getDate()).getTime()) {
        return true;
    } 
    return false;                
}

/**
 * This method validates and returns true if the supplied date value 
 * is before the current date.
 */
function isBeforeCurrentDate(date, format) {
    // Validating if the supplied date is before the current date
    if (new Date(getYear(date, getYearIndex(format)), 
            getMonth(date, getMonthIndex(format)) - 1, 
            getDate(date, getDateIndex(format))).getTime()
        < new Date(new Date().getFullYear(), 
                new Date().getMonth(), 
                new Date().getDate()).getTime()) {
        return true;
    } 
    return false;                
}

/**
 * This method validates and returns true if the supplied date value 
 * is after the current date.
 */
function isAfterCurrentDate(date, format) {
    // Validating if the supplied date is before the current date
    if (new Date(getYear(date, getYearIndex(format)), 
            getMonth(date, getMonthIndex(format)) - 1, 
            getDate(date, getDateIndex(format))).getTime()
        > new Date(new Date().getFullYear(),
                new Date().getMonth(), 
                new Date().getDate()).getTime()) {
        return true;
    } 
    return false;                
}

/**
 * This method splits the supplied date OR format based 
 * on non alpha numeric characters in the supplied string.
 */
function splitDateFormat(dateFormat) {
    // Spliting the supplied string based on non characters
    return dateFormat.split(/\W/);
}

/*
 * This method validates if the supplied value is a valid date.
 */
function isDate(date, format) {                
    // Validating if the supplied date string is valid and not a NaN (Not a Number)
    if (!isNaN(new Date(getYear(date, getYearIndex(format)), 
            getMonth(date, getMonthIndex(format)) - 1, 
            getDate(date, getDateIndex(format))))) {                    
        return true;
    } 
    return false;                                      
}

以下是HTML片段。
    <input type="text" name="start" id="start" size="10" value="05/31/2016" />
    <br/> 
    <input type="text" name="end" id="end" size="10" value="04/28/2016" />
    <br/>
    <input type="button" value="Submit" onclick="javascript:validate('MM/dd/yyyy');" />

0
为确保其正常工作,您需要对其进行验证。
function mmIsDate(str) {

    if (str == undefined) { return false; }

    var parms = str.split(/[\.\-\/]/);

    var yyyy = parseInt(parms[2], 10);

    if (yyyy < 1900) { return false; }

    var mm = parseInt(parms[1], 10);
    if (mm < 1 || mm > 12) { return false; }

    var dd = parseInt(parms[0], 10);
    if (dd < 1 || dd > 31) { return false; }

    var dateCheck = new Date(yyyy, mm - 1, dd);
    return (dateCheck.getDate() === dd && (dateCheck.getMonth() === mm - 1) && dateCheck.getFullYear() === yyyy);

};

0

如果您想验证您的日期(YYYY-MM-DD)以及与之比较,那么这将对您有所帮助...

    function validateDate()
    {
     var newDate = new Date();
     var presentDate = newDate.getDate();
     var presentMonth = newDate.getMonth();
     var presentYear = newDate.getFullYear();
     var dateOfBirthVal = document.forms[0].dateOfBirth.value;
    if (dateOfBirthVal == null) 
    return false;
    var validatePattern = /^(\d{4})(\/|-)(\d{1,2})(\/|-)(\d{1,2})$/;
    dateValues = dateOfBirthVal.match(validatePattern);
    if (dateValues == null) 
    {
        alert("Date of birth should be null and it should in the format of yyyy-mm-dd")
    return false;
        }
    var birthYear = dateValues[1];        
    birthMonth = dateValues[3];
    birthDate=  dateValues[5];
    if ((birthMonth < 1) || (birthMonth > 12)) 
    {
        alert("Invalid date")
    return false;
        }
    else if ((birthDate < 1) || (birthDate> 31)) 
    {
        alert("Invalid date")
    return false;
        }
    else if ((birthMonth==4 || birthMonth==6 || birthMonth==9 || birthMonth==11) && birthDate ==31) 
    {
        alert("Invalid date")
    return false;
        }
    else if (birthMonth == 2){ 
    var isleap = (birthYear % 4 == 0 && (birthYear % 100 != 0 || birthYear % 400 == 0));
    if (birthDate> 29 || (birthDate ==29 && !isleap)) 
    {
        alert("Invalid date")
    return false;
        }
    }
    else if((birthYear>presentYear)||(birthYear+70<presentYear))
        {
        alert("Invalid date")
        return false;
        }
    else if(birthYear==presentYear)
        {
        if(birthMonth>presentMonth+1)
            {
            alert("Invalid date")
            return false;
            }
        else if(birthMonth==presentMonth+1)
            {
            if(birthDate>presentDate)
                {
                alert("Invalid date")
                return false;
                }
            }
        }
return true;
    }

0

@mplungjan,@eduard-luca

function isDate(str) {    
    var parms = str.split(/[\.\-\/]/);
    var yyyy = parseInt(parms[2],10);
    var mm   = parseInt(parms[1],10);
    var dd   = parseInt(parms[0],10);
    var date = new Date(yyyy,mm-1,dd,12,0,0,0);
    return mm === (date.getMonth()+1) && 
        dd === date.getDate() && 
        yyyy === date.getFullYear();
}

new Date() 使用本地时间,当我们有“夏令时”或“DST(夏令时)”事件时,00:00:00 小时将显示上一天。

示例:

new Date(2010,9,17)
Sat Oct 16 2010 23:00:00 GMT-0300 (BRT)

另一种选择是使用getUTCDate()。


0

试试这个:

^\d\d[./-]\d\d[./-]\d\d\d\d$

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接