yyyymmddhhmmss

时间:2015-06-30 08:07:59

标签: java regex

我正在寻找 yyyymmddhhmmss 格式的Java正则表达式模式。它还应该检查闰年。

下面是仅检查yyyymmdd和闰年的模式,但现在我需要将其扩展到yyyymmddhhmmss(因此它包括24小时时间格式验证)。

 public static boolean isValidFormat(String format) {
    String pattern = "(?:(?:(?:(?:(?:[13579][26]|[2468][048])00)|(?:[0-9]{2}(?:(?:[13579][26])|(?:[2468][048]|0[48]))))(?:(?:(?:09|04|06|11)(?:0[1-9]|1[0-9]|2[0-9]|30))|(?:(?:01|03|05|07|08|10|12)(?:0[1-9]|1[0-9]|2[0-9]|3[01]))|(?:02(?:0[1-9]|1[0-9]|2[0-9]))))|(?:[0-9]{4}(?:(?:(?:09|04|06|11)(?:0[1-9]|1[0-9]|2[0-9]|30))|(?:(?:01|03|05|07|08|10|12)(?:0[1-9]|1[0-9]|2[0-9]|3[01]))|(?:02(?:[01][0-9]|2[0-8])))))$";
    boolean matches = Pattern.matches(pattern, format);  
    return matches;
 }

感谢。

4 个答案:

答案 0 :(得分:2)

这是验证日期时间值的非正则方法。

import java.text.*;
...
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
sdf.setLenient(false);
try {
       Date dt2 = sdf.parse("20150229105950");
       System.out.println(dt2);
}
catch (Exception exc) {
    System.out.println("NOT VALID");
}

请参阅IDEONE demo

为了使用你的正则表达式验证24小时的时间,你需要将它附加到它:

(?:0[0-9]|1[0-9]|2[0-3])(?:[0-5][0-9]){2}

(?:0[0-9]|1[0-9]|2[0-3])部分将验证从0023的数字,而(?:[0-5][0-9]){2}将验证分钟和秒数。

然后,你的正则表达式将如下:

(?:(?:(?:(?:(?:[13579][26]|[2468][048])00)|(?:[0-9]{2}(?:(?:[13579][26])|(?:[2468][048]|0[48]))))(?:(?:(?:09|04|06|11)(?:0[1-9]|1[0-9]|2[0-9]|30))|(?:(?:01|03|05|07|08|10|12)(?:0[1-9]|1[0-9]|2[0-9]|3[01]))|(?:02(?:0[1-9]|1[0-9]|2[0-9]))))|(?:[0-9]{4}(?:(?:(?:09|04|06|11)(?:0[1-9]|1[0-9]|2[0-9]|30))|(?:(?:01|03|05|07|08|10|12)(?:0[1-9]|1[0-9]|2[0-9]|3[01]))|(?:02(?:[01][0-9]|2[0-8])))))(?:0[0-9]|1[0-9]|2[0-3])(?:[0-5][0-9]){2}

请参阅demo

请注意,您正在使用强制匹配整个字符串的matches()方法,因此似乎不需要$锚点。

答案 1 :(得分:1)

如果您不需要处理闰秒(is not supported in Sun/Oracle JDK),请使用SimpleDateFormatsetLenientfalse来禁用宽松解析。这比写一个不可维护的正则表达式来解析它更好。

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SO31132861 {
    public static void main(String[] args) {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        df.setLenient(false);

        System.out.println(tryParse(df, "20160630231110"));
        System.out.println(tryParse(df, "20150228231100"));
        System.out.println(tryParse(df, "20160229231100"));

        System.out.println(tryParse(df, "21000229231100")); // 29th Feb on non-leap year 2100
        System.out.println(tryParse(df, "20160631231110")); // 31st Jun invalid day
        System.out.println(tryParse(df, "20160229231160")); // Second > 59
        System.out.println(tryParse(df, "20150229231100")); // 29th Feb on non-leap year 2015
        System.out.println(tryParse(df, "20150228241100")); // Hour > 23
    }

    private static Date tryParse(DateFormat df, String s) {
        try {
            return df.parse(s);
        } catch (ParseException e) {
            return null;
        }
    }
}

如果您需要闰秒,您可能需要查看以下答案:Are leap seconds catered for by Calendar?

答案 2 :(得分:1)

不需要正则表达式

Java具有行业领先的日期时间处理类,可在 java.time 包中找到。让他们处理输入字符串的解析,而不是搞乱正则表达式。

java.time

现代方法使用 java.time 类来取代麻烦的遗留日期时间类(DateCalendarSimpleDateFormat)。

定义格式化模式以匹配输入字符串。

String input = "20180123123456" ;  // yyyymmddhhmmss
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMddHHmmss" ) ;

Parse as a LocalDateTime因为您的输入缺少任何时区或从UTC偏移的指示。

LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
  

ldt.toString():2018-01-23T12:34:56

要捕获无效输入,请抓住DateTimeParseException

String input = "20180123123456" ; 
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMddHHmmss" ) ;
LocalDateTime ldt = null;
try {
    ldt = LocalDateTime.parse( input , f );
} catch ( DateTimeParseException e ) {
    System.out.println( "ERROR - invalid input for date-time. input: " + input ) ;
    e.printStackTrace();  // Handle invalid input.
}

顺便提一下,请注意,如果没有时区的上下文或从UTC偏移,您的输入字符串和LocalDateTime执行代表特定时刻,并且时间轴上的一个点。它们表示在大约26-27小时(最小/最大时区偏移范围)范围内的潜在时刻。

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 3 :(得分:-2)

花了一些时间详细说明,但它非常简单:

(\d{4}(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])([0-1][0-9]|2[0-4])(([0-5][0-9]){2}))

我认为这是你正在寻找的东西。您可以在regexr

中对其进行测试

干杯!