Java数据格式并非在所有情况下都适用

问题描述

我在下面的代码中犯了什么错误?如果我们不通过日期格式,例如 yyyy-MM-dd ,它将引发解析错误,并且应返回false,但在一种情况下不起作用

  • 2020-08-19->运行正常,返回true
  • 2020-19-08->这工作正常并且返回false
  • 20-08-19->这应该返回false。它无法正常工作并返回true

我不明白为什么第三种情况失败了。

澄清:我在问:如果我们通过输入20-19-08,它应该返回false,对吧?但是它返回了真实。我的问题是,如果我通过20而不是2020,则应该返回false。

代码

    public static boolean validateDateFormat(String strDate) {
        SimpleDateFormat sdfrmt = new SimpleDateFormat("yyyy-MM-dd");
        sdfrmt.setLenient(false);
        try {
            sdfrmt.parse(strDate);
        }
        catch (ParseException e) {
            return false;
        }
        return true;
    }

解决方法

20-19-08不遵循格式,因为未将年份指定为四位数字(尽管您使用的格式化程序会将20和2020识别为有效年份,而并非同一年份)和您的月份根据格式字符串的值将显示为19,这是无效的。

,

您没有在catch块中引发异常。因此,它不会抛出任何错误,只是简单地将其虚假化。要获取实际的异常,请将其抛出或将printStackTrace()抛出。

这种方法在两种情况下都适用:

import java.util.*;
import java.text.SimpleDateFormat;


public class Main{
    public static void main(String[] args) {

        String ss = "20-19-08";
        if(validateDateFormat(ss)){
            System.out.println("SUCCESS");
        }else {
            System.out.println("ERROR");
        }
        
    }
    
    public static boolean validateDateFormat(String strDate) {
        SimpleDateFormat sdfrmt = new SimpleDateFormat("yyyy-dd-MM");
        sdfrmt.setLenient(false);
        try {
            Date date = sdfrmt.parse(strDate);
            System.out.println("Formatted Date :: "+date);
            return true;
        }
        catch (Exception e) {
            return false;
        }
    }
}

测试结果:

Input : 20-19-08
Output : 

Formatted Date :: Mon Aug 19 00:00:00 UTC 20
SUCCESS

Input : 2020-19-08
Output :

Formatted Date :: Wed Aug 19 00:00:00 UTC 2020
SUCCESS
,

java.time

我认为SimpleDateFormat无法为您提供所需的验证。这是完全一样的,因为该类非常麻烦且已过时。无论如何,您都不应使用它。我建议您对所有日期工作使用现代的Java日期和时间API java.time。它很好地验证了您的日期字符串。使用DateTimeFormatter.ISO_LOCAL_DATE

public static boolean validateDateFormat(String strDate) {
    try {
        DateTimeFormatter.ISO_LOCAL_DATE.parse(strDate);
    }
    catch (DateTimeParseException e) {
        return false;
    }
    return true;
}

尝试一下:

    String candidate = "20-08-19";
    boolean valid = validateDateFormat(candidate);
    System.out.format("Is %s valid? %s%n",candidate,valid);

输出为:

Is 20-08-19 valid? false

我们也可以尝试其他一些字符串:

Is 2020-13-19 valid? false
Is 2020-08-19 and some more text that should not be here valid? false

还有一个有效的

Is 2020-08-19 valid? true

您的代码为什么不起作用?

我不明白为什么第二种情况会失败吗? 请帮助我

这是SimpleDateFormat解析数字的方式。从文档中:

  • 年份:如果格式化程序的Calendar是公历,则将应用以下规则。
    • 对于解析,如果模式字母的数量大于2,则将按字面意义解释年份,而不考虑位数。 因此,使用模式“ MM / dd / yyyy”,“ 01/11/12”将解析为12月11日 公元

我认为该示例非常符合您的情况。即使您在格式模式字符串中使用yyyySimpleDateFormat也很乐意将20解析为公元20年。这可以解释为什么不引发异常,从而导致您的方法返回true。

链接

Oracle tutorial: Date Time解释了如何使用java.time。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...