简体   繁体   中英

Regular Expression to validate a timestamp

I need a regular expression to validate a timestamp of the format, using Javascript :

YYYY/MM/DD HH:MI:SS

I tried cooking up a few, but seems my regex skills fail to cover something or other.

Please give me a reference or way to do it.

PS : I mention regex, only as a suggestion. Im using Javascript and welcome any alternative.

I would recommend to use Datejs for this. Parsing the date yourself is not necessary and a Regex is not enough to validate a timestamp. With datejs you could parse the string in a date and you'll get null if its invalid:

Date.parse("2009/06/29 13:30:10", "yyyy/MM/dd HH:mm:ss");

If you just want to validate the syntax, here is the POSIX regex:

[0-9]{1,4}/[0-9]{1,2}/[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}

But if you want to check the semantics, I would process the string using your language of choice, there are too many cases you cannot cover with regular expressions (like leap years/seconds, daylight savings, etc)

You should consider not doing this with regular expressions, but rather just run the string through DateTime with the proper format string. That way you can ensure that it is indeed a valid timestamp and not just something that looks like it.

Here is a regex I wrote earlier today for validating strings in a format similar to what you mentioned: YYYY-MM-DD hh:mm:ss . It does not identify some bad dates (for example, February 30th) but may be slightly better than using the simplistic \\d at each position. Things to note:

  1. you can specify just a date, just a time, or both date + time
  2. time can be in 12-hour or 24-hour format
  3. seconds are optional
  4. am/pm is optional

    const std::string dateAndTimeRegex = "^\\\\s*" // ignore whitespace "(" // start of date "20[123][0-9]" // year: 2010, 2011, ..., through 2039 "\\\\W" // delimiter between year and month; typically will be "-" "([0]?[0-9]|1[012])" // month: 0 through 9, or 00 through 09, or 10 through 12 "\\\\W" // delimiter between month and day; typically will be "-" "([012]?[0-9]|3[01])" // day: 0 through 9, or 00 through 29, or 30, or 31 ")?" // end of optional date "\\\\s?" // optional whitespace "(" // start of time "([01]?[0-9]|2[0-3])" // hour: 0 through 9, or 00 through 19, or 20 through 23 "\\\\W" // delimiter between hours and minutes; typically will be ":" "([0-5][0-9])" // minute: 00 through 59 "(" // start of seconds (optional) "\\\\W" // delimiter between minutes and seconds; typically will be ":" "([0-5][0-9])" // seconds: 00 through 59 ")?" // end of optional seconds "(\\\\s*[AaPp][Mm])?" // optional AM, am, PM, pm ")?" // end of optional time "\\\\s*$"; // trailing whitespace

A comment from @kyrias hints that this regex will fail in a few months once we hit the year 2020. Depending on how you use it, you'll need to change "201[0-9]" to something else.

For example, if you are looking to validate the current date +/- a few years, you could change it to "20[12][0-9]". To validate 2000 through 2099, change it to "20[0-9]{2}".

I've changed the original regex above to look for 2010-2039. Someone else can edit this answer in 20 years if necessary.

I just wrote a Regex to control a MySQL datetime (and I think that it's not so different for Oracle or other database server).

This ReGex is very secure and controls the validity of the date (months in 28, 30 & 31 days, and even years with 29/02). Then, it controls the time. The timestamp format is this one :

YYYY-MM-DD HH:MM:SS

Here is the Regex (quite long) :

((((19|20)([2468][048]|[13579][26]|0[48])|2000)-02-29|((19|20)[0-9]{2}-(0[4678]|1[02])-(0[1-9]|[12][0-9]|30)|(19|20)[0-9]{2}-(0[1359]|11)-(0[1-9]|[12][0-9]|3[01])|(19|20)[0-9]{2}-02-(0[1-9]|1[0-9]|2[0-8])))\s([01][0-9]|2[0-3]):([012345][0-9]):([012345][0-9]))

Matches

2013-04-05 17:59:59 | 2013-07-30 01:22:42 | 2099-12-30 23:59:59 | 2016-02-28 00:00:00

Non-Matches

2016-02-29 -01:01:02 | 3000-04-24 17:42:21 | 2012-03-03 24:24:02 | 2012-03-03 21:60:45

I don't think I can make a more secured one. Very functionnel and tested. Please, if you use it, don't hesitate to give me feedback ;)

FYI : If you just look for the date Regex control without time, please go there to find it : Regular Expression to match valid dates (check my post).

Cheers

function validateTimestamp(timestamp) {

    if (!/\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2}/.test(timestamp)) {
        return false;
    }

    var split = timestamp.split(/[^\d]+/);

    var year = parseFloat(split[0]);
    var month = parseFloat(split[1]);
    var day = parseFloat(split[2]);

    var hour = parseFloat(split[3]);
    var minute = parseFloat(split[4]);
    var second = parseFloat(split[5]);

    return hour < 25 && minute < 61 && second < 61 && month < 13 && day < 32;

}

For a valid date between year 1000 and year 2999 use :

String pattern = "((1\\d{3})|(20\\d{2}))-((0\\d)|(1[0-2]))-(([1-2]\\d)|(3[0-1])) (([0-1]\\d)|(2[0-3])):([0-5]\\d):([0-5]\\d)";

The months can vary between 01 and 12, the days between 01 and 31 and the time between 00:00:00 and 23:59:59.

Here is how I build up a regex matching exactly SQL Timestamp yyyy-mm-dd hh:mm:ss in the range [ 1970-01-01 00:00:00 , 2037-12-31 23:59:59 ]

$leapYear = "(19[79][26]|198[048]|20[02][048]|20[13][26])";
$leapDate = "$leapYear-02-29";

$regularYear = "(19[789][0-9]|20[012][0-9]|203[0-7])";
$regularFebruaryDate = "02-([01][1-9]|2[0-8])";
$month31Date = "(0[13578]|10|12)-([012][1-9]|3[01])";
$month30Date = "(0[469]|11)-([012][1-9]|30)";
$regularDate = "$regularYear-($regularFebruaryDate|$month30Date|$month31Date)";

$hours = "(2[0-3]|[01][0-9])";
$minutes = "[0-5][0-9]";
$seconds = "[0-5][0-9]";

$sqlTimestamp = "($leapDate|$regularDate) $hours:$minutes:$seconds";

Note: I avoided the year 2038 to have one less edge-case. The max possible SQL timestamp is 2038-01-19 03:14:07 .

perl 样式:[12]\\d{3}/[01]\\d/[0-3]\\d [0-2]\\d(?::[0-5]\\d){2}

Using

(\d\d)?\d\d\/\d\d?/\d\d? \d\d?:\d\d:\d\d

could validate the syntax, but as balpha points out, that doesn't make it a valid date.

function isTimestamp($input){
            var $regex = /^\d\d\d\d-(0?[1-9]|1[0-2])-(0?[1-9]|[12][0-9]|3[01]) (00|[0-9]|1[0-9]|2[0-3]):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9])$/;
            return $regex.test($input);
        }

check please

这是您正在寻找的正则表达式:

[0-9]{4}/(0[1-9]|1[0-2])/(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]

Regular-Expressions.info是一个很好的关于 RegEx 的信息来源,它也有一个很好的教程

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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