【问题标题】:Java data format is not working in all scenariosJava 数据格式并非适用于所有场景
【发布时间】:2020-08-21 16:41:57
【问题描述】:

我在下面的代码中犯了什么错误?如果我们不传递像 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;
    }

【问题讨论】:

  • 解析后打印日期,看看是什么。
  • 我建议你不要使用SimpleDateFormat。这个类是出了名的麻烦和过时。而是使用来自java.time, the modern Java date and time APILocalDateDateTimeFormatter
  • 嗨阿布希拉姆。我想知道我是否可以麻烦您不要在您的问题中添加乞求信息? Stack Overflow 旨在成为未来开发人员的有用问答资源,因此首选技术写作风格。无论如何,恳求通常对志愿者不起作用 - 如果可以的话,请保持中立的语气。

标签: java validation simpledateformat date-parsing


【解决方案1】:

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

【讨论】:

  • 如果我通过 20-19-08 它应该正确抛出解析错误但它不会抛出
  • 您的格式错误。 MM 代表月份,一年没有 19 个月。
  • 如果我们没有将年份作为 4 位数字传递,它应该会抛出解析错误,但它不会抛出这就是我的问题
  • 格式模式和编辑前一样。这是您的问题,无论您可能会或可能不会看到任何其他错误。作为证明,另一个答案中的代码有效,除了格式字符串不同之外,它在功能上与您的代码相同。此外,您的代码会捕获错误但只返回 false,并且什么也不抛出。
  • 我看不出这个答案如何回答所提出的问题?我倾向于将答案所说的作为人们可能期望异常的原因,但仍然没有抛出(也没有捕获)。
【解决方案2】:

您没有在 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

【讨论】:

  • @AbhiRam 它不会抛出任何错误,因为您没有在代码中使用“抛出”异常。您只是捕获异常并从那里返回 false 。要引发任何异常,请添加引发异常的代码。
  • 我在问我们是否通过输入:20-19-08 它应该返回 false 正确但它返回 true
  • @AbhiRam 你告诉你的第二种情况失败了。我无法重现您看到的失败场景。请显示一些确切的测试用例输出 ti System.out.println() 语句。同样对于您的疑问,它会同时解析 20 和 2020
  • 我的问题是如果是通过 20 而不是 2020 它应该返回 false
  • @OleV.V.:最初问题不是很清楚,现在编辑后很清楚。我认为他的代码在 19 年 8 月 20 日失败,但现在我得到了他的主要疑问。他正在使用SimpleDateFormat,它会给出这样奇怪的结果。
【解决方案3】:

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" 解析到 Jan 11, 12 公元

我认为这个例子很符合你的情况。即使您在格式模式字符串中使用 yyyySimpleDateFormat 也很乐意将 20 解析为公元 20 年。这可以解释为什么没有抛出异常,这反过来又会导致你的方法返回 true。

链接

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

【讨论】:

  • 是的,很好,正确的解释。我对此表示赞成。
猜你喜欢
  • 2021-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 2014-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多