繁体   English   中英

检查字符串是否为日期值

[英]Check if a string is a date value

检查一个值是否为有效日期的简单方法是什么,允许任何已知的日期格式。

例如,我的值10-11-200910/11/20092009-11-10T07:00:00+0000应该都被识别为日期值,而值20010350不应该被识别为日期值。 如果可能的话,最简单的检查方法是什么? 因为时间戳也将被允许。

2015年更新

这是一个老问题,但还有其他新问题,例如:

作为这个副本的副本被关闭,所以我认为在这里添加一些新信息很重要。 我写它是因为我害怕人们实际上复制和粘贴这里发布的一些代码并在生产中使用它。

这里的大多数答案要么使用一些复杂的正则表达式,这些表达式只匹配一些非常特定的格式并且实际上做错了(比如匹配 1 月 32 日,而不匹配宣传的实际 ISO 日期 - 请参阅演示),或者他们尝试将任何内容传递给Date构造函数并希望一切顺利。

使用时刻

正如我在这个答案中所解释的,目前有一个可用的库: Moment.js

它是一个在 JavaScript 中解析、验证、操作和显示日期的库,它具有比标准 JavaScript 日期处理函数更丰富的 API。

它是 12kB 压缩/gzipped 并在 Node.js 和其他地方工作:

bower install moment --save # bower
npm install moment --save   # npm
Install-Package Moment.js   # NuGet
spm install moment --save   # spm
meteor add momentjs:moment  # meteor

使用 Moment,您可以非常具体地检查有效日期。 有时,添加一些有关您期望的格式的线索非常重要。 例如,诸如 06/22/2015 之类的日期看起来像是一个有效日期,除非您使用 DD/MM/YYYY 格式,在这种情况下,应将该日期视为无效日期而拒绝。 有几种方法可以告诉 Moment 您期望的格式,例如:

moment("06/22/2015", "MM/DD/YYYY", true).isValid(); // true
moment("06/22/2015", "DD/MM/YYYY", true).isValid(); // false

true论点在那里,所以如果输入不完全符合所提供的格式之一,则 Moment 不会尝试解析输入(在我看来,这应该是默认行为)。

您可以使用内部提供的格式:

moment("2015-06-22T13:17:21+0000", moment.ISO_8601, true).isValid(); // true

您可以使用多种格式作为数组:

var formats = [
    moment.ISO_8601,
    "MM/DD/YYYY  :)  HH*mm*ss"
];
moment("2015-06-22T13:17:21+0000", formats, true).isValid(); // true
moment("06/22/2015  :)  13*17*21", formats, true).isValid(); // true
moment("06/22/2015  :(  13*17*21", formats, true).isValid(); // false

见:演示

其他图书馆

如果您不想使用 Moment.js,还有其他库:

2016年更新

我创建了immoment模块,它类似于 Moment(的一个子集),但没有由现有对象的突变引起的意外(有关更多信息,请参阅文档)。

2018 更新

今天,我建议使用Luxon进行日期/时间操作,而不是 Moment,后者(与 Moment 不同)使所有对象不可变,因此不会出现与日期隐式突变相关的令人讨厌的意外。

更多信息

也可以看看:

Rob Gravelle 关于 JavaScript 日期解析库的一系列文章:

底线

当然,任何人都可以尝试重新发明轮子,编写正则表达式(但在开始之前实际阅读 ISO 8601 和 RFC 3339)或使用随机数据调用内置构造函数来解析诸如'Invalid Date''Invalid Date'错误消息(是吗?确定此消息在所有平台上都完全相同?在所有语言环境中?将来?)或者您可以使用经过测试的解决方案并花时间改进它,而不是重新发明它。 这里列出的所有库都是开源的免费软件。

这就是我在我现在正在开发的应用程序中解决这个问题的方法:

根据 krillgar 的反馈更新:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}

Date.parse()就足够了吗?

请参阅其相关的MDN 文档页面

如果字符串日期有效,则Date.parse返回时间戳。 以下是一些用例:

// /!\ from now (2021) date interpretation changes a lot depending on the browser
Date.parse('01 Jan 1901 00:00:00 GMT') // -2177452800000
Date.parse('01/01/2012') // 1325372400000
Date.parse('153') // NaN (firefox) -57338928561000 (chrome)
Date.parse('string') // NaN
Date.parse(1) // NaN (firefox) 978303600000 (chrome)
Date.parse(1000) // -30610224000000 from 1000 it seems to be treated as year
Date.parse(1000, 12, 12) // -30610224000000 but days and month are not taken in account like in new Date(year, month,day...)
Date.parse(new Date(1970, 1, 0)) // 2588400000
// update with edge cases from comments
Date.parse('4.3') // NaN (firefox) 986248800000 (chrome)
Date.parse('2013-02-31') // NaN (firefox) 1362268800000 (chrome)
Date.parse("My Name 8") // NaN (firefox) 996616800000 (chrome)

new Date(date) === 'Invalid Date'仅适用于 Firefox 和 Chrome。 IE8(我在我的机器上用于测试目的的那个)给出了 NaN。

正如接受的答案所述, Date.parse(date)也适用于数字。 因此,为了解决这个问题,您还可以检查它是否不是数字(如果您想确认的话)。

var parsedDate = Date.parse(date);

// You want to check again for !isNaN(parsedDate) here because Dates can be converted
// to numbers, but a failed Date parse will not.
if (isNaN(date) && !isNaN(parsedDate)) {
    /* do your work */
}
function isDate(dateStr) {
  return !isNaN(new Date(dateStr).getDate());
}
  • 这将适用于任何浏览器,因为它不依赖于“无效日期”检查。
  • 这将适用于 ES6 之前的遗留代码。
  • 这将在没有任何库的情况下工作。
  • 无论日期格式如何,这都将起作用。
  • 这不依赖于 Date.parse 当像“蜘蛛侠 22”这样的值在日期字符串中时,它会失败。
  • 这并不要求我们编写任何 RegEx。

这样的事情怎么样? 它将测试它是 Date 对象还是日期字符串:

function isDate(value) {
    var dateFormat;
    if (toString.call(value) === '[object Date]') {
        return true;
    }
    if (typeof value.replace === 'function') {
        value.replace(/^\s+|\s+$/gm, '');
    }
    dateFormat = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/;
    return dateFormat.test(value);
}

我应该提一下,这不会测试 ISO 格式的字符串,但对 RegExp 做更多的工作,你应该会很好。

这里的答案都没有解决检查日期是否无效的问题,例如 2 月 31 日。此函数通过检查返回的月份是否等于原始月份并确保提供了有效年份来解决该问题。

//expected input dd/mm/yyyy or dd.mm.yyyy or dd-mm-yyyy
function isValidDate(s) {
  var separators = ['\\.', '\\-', '\\/'];
  var bits = s.split(new RegExp(separators.join('|'), 'g'));
  var d = new Date(bits[2], bits[1] - 1, bits[0]);
  return d.getFullYear() == bits[2] && d.getMonth() + 1 == bits[1];
} 

使用正则表达式来验证它。

isDate('2018-08-01T18:30:00.000Z');

isDate(_date){
        const _regExp  = new RegExp('^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$');
        return _regExp.test(_date);
    }

通过参考以上所有评论,我得出了一个解决方案。

如果传递的Date为 ISO 格式或需要处理其他格式,则此方法有效。

var isISO = "2018-08-01T18:30:00.000Z";

if (new Date(isISO) !== "Invalid Date" && !isNaN(new Date(isISO))) {
    if(isISO == new Date(isISO).toISOString()) {
        console.log("Valid date");
    } else {
        console.log("Invalid date");
    }
} else {
    console.log("Invalid date");
}

你可以在这里玩 JSFiddle。

这是一个仅使用Date.parse()的改进函数:

function isDate(s) {
    if(isNaN(s) && !isNaN(Date.parse(s)))
        return true;
    else return false;
}

注意: Date.parse() 将解析数字:例如Date.parse(1)将返回一个日期。 所以在这里我们检查s是否不是数字,如果它是日期。

我觉得没有一个答案正确理解 OP 的要求。 这里的问题是 JavaScript 可以将任何数字解析为有效日期,因为Date对象可以将像'3000'这样的字符串解析为年份,并将返回一个有效的 Date 实例:

new Date('3000')

> Wed Jan 01 3000 02:00:00 GMT+0200 (Eastern European Standard Time)

为了解决这个问题,我们可以通过传入第三个参数在严格模式下使用Day.js库的解析方法。 它记录在他们的String + Format页面中。 为了基于格式进行解析,我们还必须启用CustomParseFormat插件。 我假设你可以在这里使用 ESM 导入或者设置一个像 Webpack 这样的编译器

import dayjs from 'dayjs'
import formatParser from 'dayjs/plugin/customParseFormat'

dayjs.extend(formatParser)

dayjs('3000', 'YYYY-MM-DD', true).isValid()

> false

我会这样做

var myDateStr= new Date("2015/5/2");

if( ! isNaN ( myDateStr.getMonth() )) {
    console.log("Valid date");
}
else {
    console.log("Invalid date");
}

在这里

我知道这是一个老问题,但我遇到了同样的问题,发现没有一个答案正常工作 - 特别是从日期中剔除数字(1,200,345 等),这是原始问题。 这是我能想到的一种相当非正统的方法,它似乎有效。 请指出是否有失败的情况。

if(sDate.toString() == parseInt(sDate).toString()) return false;

这是清除数字的行。 因此,整个函数可能如下所示:

 function isDate(sDate) { if(sDate.toString() == parseInt(sDate).toString()) return false; var tryDate = new Date(sDate); return (tryDate && tryDate.toString() != "NaN" && tryDate != "Invalid Date"); } console.log("100", isDate(100)); console.log("234", isDate("234")); console.log("hello", isDate("hello")); console.log("25 Feb 2018", isDate("25 Feb 2018")); console.log("2009-11-10T07:00:00+0000", isDate("2009-11-10T07:00:00+0000"));

这是一个极简版本。

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}

在尝试了上面列出的所有答案之后,我得出以下结论:

var checkDateValue = function(date) {
    return date && (!(new Date(date) == "Invalid Date") && !isNaN(new Date(date)));
};

请注意, new Date(date) !== "Invalid Date" 始终为 true。 希望这可以帮助。

这个可调用函数完美运行,对于有效日期返回 true。 请务必使用 ISO 格式的日期(yyyy-mm-dd 或 yyyy/mm/dd)调用:

function validateDate(isoDate) {

    if (isNaN(Date.parse(isoDate))) {
        return false;
    } else {
        if (isoDate != (new Date(isoDate)).toISOString().substr(0,10)) {
            return false;
        }
    }
    return true;
}

检查对象是否可以使用与日期相关的函数以查找它是否是日期对象是否可以?

喜欢

var l = new Date();
var isDate = (l.getDate !== undefined) ? true; false;

可以使用以下答案验证日期

//format the date values dd-mm-yyyy or dd/mm/yyyy into following variables year month and date
 var year=2019;
 var month=2;
 var date=31;
 var d = new Date(year, month - 1, date);
 if (d.getFullYear() != year
    || d.getMonth() != (month - 1)
    || d.getDate() != date) {
alert("invalid date");
return false;
}else{
alert("Valid date");
}

好的,这是一个老问题,但我在此处检查解决方案时找到了另一个解决方案。 对我来说,检查函数 getTime() 是否存在于日期对象中:

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}

我为此创建了一个基于基于moment.js的解决方案,以检测ISO 8601,RFC 2822和本地格式,而无需指定解析字符串(我始终不希望输入“标准”格式。)...

https://github.com/patarapolw/valid-moment

一个简短的方法:

if(!isNaN(Date.parse(date)))

我发现这个解决方案非常好:

const DateTime = require('luxon').DateTime;

isDateValid(stringDate) {
  let date = DateTime.fromFormat(stringDate, 'd-M-y');
  if (date.invalid === null) {
    return date.toJSDate();
  }
  date = DateTime.fromFormat(stringDate, 'd,M,y');
  if (date.invalid === null) {
    return date.toJSDate();
  }
  date = DateTime.fromFormat(stringDate, 'y-M-d');
  if (date.invalid === null) {
    return date.toJSDate();
  }
  date = DateTime.fromFormat(stringDate, 'y,M,d');
  if (date.invalid === null) {
    return date.toJSDate();
  }
  date = DateTime.fromFormat(stringDate, 'y.M.d');
  if (date.invalid === null) {
    return date.toJSDate();
  }
  date = DateTime.fromFormat(stringDate, 'd.M.y');
  if (date.invalid === null) {
    return date.toJSDate();
  }
  date = DateTime.fromFormat(stringDate, 'y/M/d');
  if (date.invalid === null) {
    return date.toJSDate();
  }
  date = DateTime.fromFormat(stringDate, 'd/M/y');
  if (date.invalid === null) {
    return date.toJSDate();
  }
  return false;
}

isDateValid('30.12.86'); //true
isDateValid('30/12/86'); //true
isDateValid('86-12-40'); //false

并且您可以轻松添加更多格式

我认为最直接的解决方案是

if (Date.parse(yourDate) > 0) ? true : false;

如果不是有效日期,则为 NaN,大于 0。

我相信这是仅包含数字的日期最简单的工作答案:

var rst = Date.parse(sDate.replaceAll(" ",""));
if(rst===NaN) console.log("not a date");
else console.log("a great date")

通过删除空格,您可以检测到像“hello 2”这样被当作日期的值。 对于包含日期名称或月份名称等字符串的日期......我相信这是关于字符串验证的。

这就是我最终这样做的方式。 这不会涵盖所有格式。 你必须相应地调整。 我可以控制格式,所以它对我有用

function isValidDate(s) {
            var dt = "";
            var bits = [];
            if (s && s.length >= 6) {
                if (s.indexOf("/") > -1) {
                    bits = s.split("/");
                }
                else if (s.indexOf("-") > -1) {
                    bits = s.split("-");
                }
                else if (s.indexOf(".") > -1) {
                    bits = s.split(".");
                }
                try {
                    dt = new Date(bits[2], bits[0] - 1, bits[1]);
                } catch (e) {
                    return false;
                }
                return (dt.getMonth() + 1) === parseInt(bits[0]);
            } else {
                return false;
            }
        }

试试这个

<input type="text" id="StartDay" value="2018/01/01" maxlength="10" />

$('#StartDay').change(function () {
    if ( ($('#StartDay').val().length == 10 && new Date($('#StartDay').val()) >= new Date("2018/01/01") &&
        (new Date($('#StartDay').val()) !== "Invalid Date") && !isNaN(new Date($('#StartDay').val()))) == false) {
     .....
    }
})

没有成功地与问题相关但...

检查ISO数据(ES6功能方式)

 const isISODate = date => new Date(date) !== "Invalid Date" && !isNaN(new Date(date)) && date == new Date(date).toISOString(); console.log( isISODate("2018-08-01T18:30:00.000Z") ); 

 document.getElementById('r1').innerHTML = dayjs('sdsdsd').isValid() document.getElementById('r2').innerHTML = dayjs('2/6/20').isValid()
 <script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script> <p>'sdsdsd' is a date: <span id="r1"></span></p> <p>'2/6/20' is a date: <span id="r2"></span></p>

一个轻量级的库已经为你准备好了: Day.js

此函数验证格式为 m/d/yyyy 或 mm/dd/yyyy 的输入字符串是否可以转换为日期,并且该日期是与输入字符串匹配的有效日期。 添加更多条件检查以验证其他格式。

/**
 * Verify if a string is a date
 * @param {string} sDate - string that should be formatted m/d/yyyy or mm/dd/yyyy
 * @return {boolean} whether string is a valid date
 */
function isValidDate(sDate) {
  let newDate = new Date(sDate);
  console.log(sDate + " date conversion: " + newDate);
  let isDate = (!isNaN(newDate.getTime()));
  console.log(sDate + " is a date: " + isDate);
  if (isDate) {
    let firstSlash = sDate.indexOf("/");
    let secondSlash = sDate.indexOf("/",firstSlash+1);
    let originalDateString = parseInt(sDate.slice(0,firstSlash),10) + "/" + parseInt(sDate.slice(firstSlash+1,secondSlash),10) + "/" + parseInt(sDate.slice(secondSlash+1),10);
    let newDateString = (newDate.getMonth()+1) + "/" + (newDate.getDate()) + "/" + (newDate.getFullYear());
    isDate = (originalDateString == newDateString);
    console.log(originalDateString + " matches " + newDateString + ": " + isDate);
  }
  return isDate;
}

这是可以用来验证输入是可以转换为date objectnumberstring的方法。

它涵盖以下情况:

  1. 捕获导致"Invalid Date" date constructor结果的任何输入;
  2. 从技术角度捕捉日期“有效”但从业务逻辑角度来看无效的情况,例如
  • new Date(null).getTime(): 0
  • new Date(true).getTime(): 1
  • new Date(-3.14).getTime(): -3
  • new Date(["1", "2"]).toDateString(): Tue Jan 02 2001
  • new Date([1, 2]).toDateString(): Tue Jan 02 2001
function checkDateInputValidity(input, lowerLimit, upperLimit) {
    // make sure the input is a number or string to avoid false positive correct dates:
    if (...) {
        return false
    }
    // create the date object:
    const date = new Date(input)
    // check if the Date constructor failed:
    if (date.toDateString() === 'Invalid Date') {
        return false
    }
    // check if the Date constructor succeeded, but the result is out of range:
    if (date < new Date(lowerLimit) || date > new Date(upperLimit)) {
        return false
    }
    return true
}

// const low = '2021-12-31T23:59:59'
// const high = '2025-01-01T00:00:00'

检查值是否为有效日期(允许使用任何已知的日期格式)的简便方法是什么。

例如我具有值10-11-200910/11/20092009-11-10T07:00:00+0000应该所有被识别为日期值,并且这些值20010350 ,其不应被识别为日期值。 如果可能的话,最简单的检查方法是什么? 因为时间戳也将被允许。

检查值是否为有效日期(允许使用任何已知的日期格式)的简便方法是什么。

例如我具有值10-11-200910/11/20092009-11-10T07:00:00+0000应该所有被识别为日期值,并且这些值20010350 ,其不应被识别为日期值。 如果可能的话,最简单的检查方法是什么? 因为时间戳也将被允许。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM