我正在寻找 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;
}
感谢。
答案 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])
部分将验证从00
到23
的数字,而(?:[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),请使用SimpleDateFormat
和setLenient
到false
来禁用宽松解析。这比写一个不可维护的正则表达式来解析它更好。
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 类来取代麻烦的遗留日期时间类(Date
,Calendar
,SimpleDateFormat
)。
定义格式化模式以匹配输入字符串。
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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance 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的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 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
中对其进行测试干杯!