【问题标题】:Regular Expression to validate a timestamp正则表达式验证时间戳
【发布时间】:2009-06-29 10:58:40
【问题描述】:

我需要一个正则表达式来验证格式的时间戳,使用 Javascript

YYYY/MM/DD HH:MI:SS

我尝试了一些,但似乎我的正则表达式技能无法涵盖某些内容。

请给我一个参考或方法。

附言: 我提到正则表达式,只是作为一个建议。我正在使用 Javascript,欢迎任何替代方案。

【问题讨论】:

  • 2009/14/35 27:63:60 有效吗?如果没有,正则表达式会很难看。
  • 您使用什么语言?如果这是 Perl,您可以从正则表达式调用代码,这可能是您进行易于阅读的检查的唯一方法。只是验证是否是闰年的代码来验证 2 月 29 日是否存在会使事情变得丑陋,因为所有人都出去了。
  • 我提到正则表达式,只是作为一个建议。我使用 Javascript,欢迎任何替代方案。
  • 验证的目的是什么?如果您真的想确保它是有效日期,请将其解析为日期。正则表达式会简单地告诉你它是否看起来像一个日期,大多数库函数都会将其作为解析的第一部分!

标签: javascript regex validation timestamp


【解决方案1】:

如果您只想验证语法,这里是 POSIX 正则表达式:

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

但是如果你想检查语义,我会使用你选择的语言处理字符串,有太多的情况你不能用正则表达式覆盖(比如闰年/秒、夏令时等)

【讨论】:

  • 我认为最好是 [0-9]{4,4}/[0-9]{2,2}/[0-9]{2,2} [ 0-9]{2,2}:[0-9]{2,2}:[0-9]{2,2}
  • 根据您的需要,可以。但您可以使用 {x} 代替 {x,x}。
【解决方案2】:
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;

}

【讨论】:

    【解决方案3】:

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

    [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]
    

    【讨论】:

      【解决方案4】:

      这是我今天早些时候编写的一个正则表达式,用于以类似于您提到的格式验证字符串:YYYY-MM-DD hh:mm:ss。它不会识别一些糟糕的日期(例如,2 月 30 日),但可能比在每个位置使用简单的 \d 稍微好一些。注意事项:

      1. 您可以仅指定日期、仅指定时间或同时指定日期+时间
      2. 时间可以是 12 小时或 24 小时格式
      3. 秒是可选的
      4. 上午/下午是可选的

        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
        

      @kyrias 的评论暗示,一旦我们到了 2020 年,这个正则表达式将在几个月内失效。根据您使用它的方式,您需要将“201[0-9]”更改为其他内容。

      例如,如果您希望验证当前日期 +/- 几年,您可以将其更改为“20[12][0-9]”。要验证 2000 到 2099,请将其更改为“20[0-9]{2}”。

      我已将上面的原始正则表达式更改为查找 2010-2039。如有必要,其他人可以在 20 年内编辑此答案。

      【讨论】:

      • 三个月后,任何使用这个正则表达式的东西都会坏掉。
      • 一切都坏了
      • @Bolster Care 解释一下?
      【解决方案5】:

      我建议为此使用Datejs。不需要自己解析日期,并且正则表达式不足以验证时间戳。使用 datejs,您可以解析日期中的字符串,如果它无效,您将得到 null:

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

      【讨论】:

        【解决方案6】:

        这是我如何构建一个与范围内的 SQL 时间戳 yyyy-mm-dd hh:mm:ss 完全匹配的正则表达式 [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";
        

        注意:我避开了 2038 年,以减少一个极端情况。最大可能的 SQL 时间戳为 2038-01-19 03:14:07

        【讨论】:

          【解决方案7】:

          我刚刚编写了一个正则表达式来控制 MySQL 日期时间(我认为对于 Oracle 或其他数据库服务器来说并没有太大的不同)。

          这个正则表达式非常安全,可以控制日期的有效性(28、30 和 31 天的月份,甚至 29/02 的年份)。然后,它控制时间。 时间戳格式是这样的:

          YYYY-MM-DD HH:MM:SS

          这是正则表达式(很长):

          ((((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]))
          

          匹配

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

          不匹配

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

          我不认为我可以制作一个更安全的。非常实用且经过测试。 请,如果您使用它,请不要犹豫给我反馈;)

          仅供参考:如果您只是在没有时间的情况下寻找日期正则表达式控件,请到那里找到它:Regular Expression to match valid dates (查看我的帖子)。

          干杯

          【讨论】:

            【解决方案8】:

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

            【讨论】:

            • 我们将不胜感激。我不明白为什么应该拒绝提供指向 RegEx 参考网站的链接,尤其是当它在“请给我参考或方法”的问题中声明时。
            【解决方案9】:

            您应该考虑不使用正则表达式执行此操作,而只需使用正确的格式字符串通过 DateTime 运行字符串。这样您就可以确保它确实是一个有效的时间戳,而不仅仅是看起来像的东西。

            【讨论】:

              【解决方案10】:

              对于 1000 年和 2999 年之间的有效日期,请使用:

              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)";
              

              月份可以在 01 到 12 之间、天在 01 到 31 之间以及时间在 00:00:00 到 23:59:59 之间变化。

              【讨论】:

                【解决方案11】:

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

                【讨论】:

                • 如果你不需要闰秒。
                【解决方案12】:

                使用

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

                可以验证语法,但正如 balpha 指出的那样,这并不能使其成为有效日期。

                【讨论】:

                  【解决方案13】:
                  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);
                          }
                  

                  请检查

                  【讨论】:

                    猜你喜欢
                    • 2018-08-11
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2014-12-15
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多