我怎样才能禁止javascript中的宽松日期?

时间:2014-03-04 15:57:18

标签: javascript regex date

我正在尝试验证字符串是否为有效日期。 Date.parse(dateString)new Date(dateString)都非常宽松。例如,14/14/2000之类的日期将显示为2/14/2001。我尝试了正则表达式,但现在我需要验证超过mm/dd/yyyy,我还需要验证yyyy-mm-ddThh:mm:ss,例如1951-02-05T00:00:00

我现在正在使用正则表达式和一些基本日期检查,但上面的第二个日期格式是正则表达式失败。

function isDate(dateToCheck) {
    if (dateToCheck == "" || dateToCheck == null) { return true; }
    var timestamp = Date.parse(dateToCheck);
    var d = new Date(timestamp);
    var re = /(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d/;

    var valid = re.test(dateToCheck);
    valid = valid && !isNaN(timestamp);
    valid = valid && d.getFullYear() > 1900 && d.getFullYear() < 2100;
    return valid;
}

正则表达式专门用于mm/dd/yyyy,其中月份和日期都是两位数(单个数字月份获得前导零)并且不允许无效的月份或天数,例如14个月或32个一天。这一年可以是1900年到2099年之间的任何事情。

这不是气密的。它将允许02/31/2000这是无效的,因为2月永远不会有31天。

如何在不允许宽松日期的情况下验证这两种日期格式?

3 个答案:

答案 0 :(得分:3)

查看moment.js及其所有解析选项。

http://momentjs.com/docs/#/parsing/string/

它们是一个isValid()函数,可用于验证输入字符串是否正确。

moment("not a real date").isValid(); // false

如果您使用日期验证字符串进行梳理,那么您将获得所需的结果: http://momentjs.com/docs/#/parsing/string-formats/

var m = moment('14/14/2000', 'DD/MM/YYYY');
console.log(m.toString(),m.isValid());
//"Not a valid date"
//false

更新:我创建了一个test harness on JS-Bin with your full sample data.这是使用Moment.js的完整工作示例代码。您可以指定多种格式,然后才能返回isValid()

function momentIsDate (dateToCheck) {
  return moment(dateToCheck, [
    'DD/MM/YYYY',
    'YYYY-MM-DDTHH:mm:ss'
  ]).isValid();
}

答案 1 :(得分:1)

您可以以非常酷的方式对自己使用“宽松日期”功能来处理此问题。首先使用mm/dd/yyyy示例,首先确保该值与该格式匹配,然后,如果匹配,则使用该值创建新的Date对象:

var checkDateVal = new Date(dateToCheck);

然后,使用该新值重建日期字符串:

var checkDateMonth = checkDateVal.getDate();
var checkDateDay = checkDateVal.getMonth() + 1;
var checkDateYear = checkDateVal.getFullYear();

// force two digits for the day and month, if necessary
checkDateMonth = (checkDateMonth < 10) ? "0" + checkDateMonth : checkDateMonth;
checkDateDay = (checkDateDay < 10) ? "0" + checkDateDay : checkDateDay;

var checkDateString = checkDateMonth + "/" + checkDateDay + "/" + checkDateYear;

现在将原始日期输入与您创建的新字符串值进行比较:

if (dateToCheck !== checkDateString) {
    // Yell at user for bad data
}

如果用户输入的日期字符串与Date对象创建的日期字符串不匹配,则表示该对象被强制“按下”输入值以创建实际日期。 。 。这意味着原始输入值是一个无效的日期值。

还有你的支票。 :)

同样的逻辑可以应用于您提到的更长日期格式。 。 。我建议在开头使用两个正则表达式值来确定原始输入所在的格式,然后将其用作驱动下游逻辑的标志(例如,需要如何构建checkDateString以查看是否输入有效)。

答案 2 :(得分:1)

他们都可以用这个验证。

 #  /^(?:(?:(?:19|20)\d\d[- \/.](?:0[1-9]|1[012])[- \/.](?:0[1-9]|[12][0-9]|3[01])T\d{2}:\d{2}:\d{2})|(?:(?:0[1-9]|1[012])[- \/.](?:0[1-9]|[12][0-9]|3[01])[- \/.](?:19|20)\d{2}))$/

 ^ 
 (?:
      (?:
           (?: 19 | 20 )
           \d\d [- /.] 
           (?: 0 [1-9] | 1 [012] )
           [- /.] 
           (?: 0 [1-9] | [12] [0-9] | 3 [01] )
           T \d{2} : \d{2} : \d{2} 
      )
   |  (?:
           (?: 0 [1-9] | 1 [012] )
           [- /.] 
           (?: 0 [1-9] | [12] [0-9] | 3 [01] )
           [- /.] 
           (?: 19 | 20 )
           \d{2} 
      )
 )
 $