java - 在java中验证日期和时间戳

标签 java date

我需要在java中验证日期输入日期可以是类似的

01-01-2019,2019-01-01,2019/01/01,2019/01/01,2017-02-14 19:30. 

我有以下代码可以验证没有时间戳的简单日期。我还需要使用时间戳验证日期。在下面的代码中,我编写了一个 parseDate 方法,它为我提供了我们传递的日期格式。

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

  public static void main(String[] args) {

        String date1 = parseDate("12-12-2019 10:10:10");
        boolean str1 = isValid(date1,"12-12-2019 10:10:10");
        System.out.println("str = " + str1);
  }

  private static final String[] formats = { 
  "yyyy-MM-dd'T'HH:mm:ss'Z'","yyyy-MM-dd'T'HH:mm:ssZ",
"yyyy-MM-dd'T'HH:mm:ss","yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
"yyyy-MM-dd'T'HH:mm:ss.SSSZ","yyyy-MM-dd HH:mm:ss", 
"MM/dd/yyyy HH:mm:ss","MM/dd/yyyy'T'HH:mm:ss.SSS'Z'", 
"MM/dd/yyyy'T'HH:mm:ss.SSSZ", "MM/dd/yyyy'T'HH:mm:ss.SSS", 
"MM/dd/yyyy'T'HH:mm:ssZ","MM/dd/yyyy'T'HH:mm:ss", 
"yyyy:MM:dd HH:mm:ss","yyyy-MM-dd HH:mm:ss.SSSSSS",
"yyyy/MM/dd HH:mm:ss","MM/dd/yyyy","dd/MM/yyyy",
"dd-MM-yyyy","yyyy/MM/dd"
   };

    public static String parseDate(String dateString) {
        int count = 0;

                    if (dateString != null) {
            for (String dateFormat : formats) {
                SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
                sdf.setLenient(false);

                try {
                    count ++;
                    sdf.parse(dateString);
                    System.out.println("sdf.parse(dateString);" + sdf.parse(dateString));
                    System.out.println("dateFormat  " + dateFormat);
                    System.out.println("count" + count);
                    return dateFormat;
                } catch (ParseException e) {
              }
            }
        }
        return "yyyy-MM-dd";
    }

  public static boolean isValid(String format,String inDate) {

    System.out.println("format  " + format);
    System.out.println("inDate  " + inDate);

    if (inDate == null || !inDate.matches("^([0-2][0-9]|(3)[0-1])(\\-)(((0)[0-9])|((1)[0-2]))(\\-)\\d{4}$")
    && !inDate.matches("^([0-2][0-9]|(3)[0-1])(\\/)(((0)[0-9])|((1)[0-2]))(\\/)\\d{4}$") 
    && !inDate.matches("([12]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01]))")
    && !inDate.matches("([12]\\d{3}/(0[1-9]|1[0-2])/(0[1-9]|[12]\\d|3[01]))"))
    return false;
    SimpleDateFormat df = new SimpleDateFormat(format);
    try {
        df.parse(inDate);
        return true;
    } catch (ParseException ex) {
        return false;
    }


}

最佳答案

不可能容纳所有格式

"MM/dd/yyyy","dd/MM/yyyy"

不可能准确解析这样的值。

01/02/2020 是二月一号还是一月二号?没有办法知道。

避免遗留日期时间类

您使用了错误的类。 切勿使用DateSimpleDateFormatCalendar等。仅使用java.time类。

  • Date 类表示一个时刻,而不是日期或日期与时间。时刻是一个日期、一天中的时间以及与 UTC 或时区的偏移量。
  • 几年前,随着 JSR 310 的采用,这个可怕的类已被 java.time.Instant 取代。

ISO 8601

顺便说一下,ISO 8601标准定义了将日期时间值作为文本交换的实用格式。这些格式易于机器解析,也易于跨文化的人类阅读。

我建议您向数据发布者介绍这些标准格式。

提示:现代 java.time 类在解析/生成字符串时默认使用这些格式。因此无需指定格式模式。

本地日期

LocalDate类表示仅日期值,没有日期时间,也没有 time zoneoffset-from-UTC .

DateTimeFormatter

为每种期望的格式定义一个DateTimeFormatter

请注意我如何更改您的示例数据以使用 23 表示月份中的某一天,以区分月份和日期。如果您的实际输入可以是任一顺序,那么您的工作就不可能完成。您应该将这个问题推回给发布此类随意的格式不良数据的人。

List< DateTimeFormatter > formatters = 
    List.of(
        DateTimeFormatter.ofPattern( "MM-dd-uuuu" ) ,  // 01-23-2019
        DateTimeFormatter.ISO_LOCAL_DATE ,             // 2019-01-23
        DateTimeFormatter.ofPattern( "uuuu/MM/dd" )    // 2019/01/23
    )
;

循环该列表来尝试每一个,在不合适时捕获异常。

LocalDate localDate = null ;
for( DateTimeFormatter f : formatters ) {
    try{
        localDate = LocalDate.parse( input , f ) ;
    } catch ( DateTimeParseException e ) {
        // Ignoring exception, as it is expected. 
    }
}
if( Objects.isNull( localDate ) ) { … deal with unexpected input }

本地日期时间

并检查输入的长度以检测带时间的日期输入与仅日期输入。

if( input.length() > 10 ) {  
    DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm" ) ;  // 2017-02-14 19:30
    LocalDateTime ldt = LocalDateTime.parse( input , f ) ;  // Add trap for `DateTimeParseException`. 
}

示例应用

这是一个完整的工作示例应用程序。

/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

import java.time.* ;
import java.time.format.* ;
import java.time.temporal.* ;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {

List< DateTimeFormatter > formatters = 
    List.of(
        DateTimeFormatter.ofPattern( "MM-dd-uuuu" ) ,  // 01-23-2019
        DateTimeFormatter.ISO_LOCAL_DATE ,             // 2019-01-23
        DateTimeFormatter.ofPattern( "uuuu/MM/dd" )    // 2019/01/23
    )
;

List< String > inputs = 
    List.of(
        "01-23-2019" , 
        "2019-01-23" ,
        "2019/01/23" ,
        "banana"
    )
;

for( String input : inputs ) {
    LocalDate localDate = null ;
    for( DateTimeFormatter formatter : formatters ) 
    {
        try{
            localDate = LocalDate.parse( input , formatter ) ;
        } catch ( DateTimeParseException e ) {
            // Ignoring exception, as it is expected. 
        }
    }
    if( Objects.isNull( localDate ) ) 
    { // Deal with unexpected input 
        System.out.println( "ERROR: Unexpected input: " + input ) ;
    } else {
        System.out.println( "Input: " + input + " ➙ " + localDate.toString() ) ;
    }
}



    }
}

查看run live at IdeOne.com .

Input: 01-23-2019 ➙ 2019-01-23

Input: 2019-01-23 ➙ 2019-01-23

Input: 2019/01/23 ➙ 2019-01-23

ERROR: Unexpected input: banana

关于java - 在java中验证日期和时间戳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57451945/

相关文章:

java - 以接口(interface)作为参数的方法

java - 如何使我在 MySQL 数据库中的主键适用于小写和大写?

java - 使用多个属性对对象列表进行分组

sql-server-2008 - MS-Access 前端无法识别来自 SQL Server 的日期

ios - 在 Swift 中用包含时间的字符串替换当前日期

java - 使用JAVA为EC2实例设置标签

java - Python boolean 语句

java - 使用 simpleDateFormat 将字符串转换为 Util Date 不起作用

python - 将字符串列表中的元素和下一个元素转换为 python 中的日期

c++ - 如何判断我的 struct tm 是否处于无效状态?