【问题标题】:Is this Date a valid one in Java?这个日期在 Java 中是有效的吗?
【发布时间】:2017-07-19 14:13:34
【问题描述】:

00/00/00 是 Java 中 MM/dd/yy 格式的有效日期吗?

我在下面的示例代码中尝试了这个,以查看 00/00/00 在 Java 中是否有效。但是,被解析的日期是SUN Nov 30 00:00:00 IST 2

public static void main(String[] args) {

System.out.println(new SimpleDateFormat("MM/dd/yy").parse("00/00/00"));

}

如果不是,我如何在 Java 中解析 "00/00/00" 格式的日期字符串 MM/dd/yy

问题是我需要读取字符串00/00/00,它是在文本文件中获得的。在此过程中,当我使用 SimpleDateFormatparse() 方法解析该字符串时,我得到了 SUN Nov 30 00:00:00 IST 2 作为输出。但是,我期待第 0 年、第 0 天、第 0 个月作为输出。你认为这可能吗?

感谢您的宝贵时间。

【问题讨论】:

  • 为什么需要将00/00/00解析为Date?什么是零月和零天?我没有看到这里的重点......
  • 试试simpleDateFormat.setLenient(false);。默认情况下,SimpleDateFormat 会尽力提供帮助。有时它很有帮助,并且可以愉快地解析这样的乱码日期
  • 这听起来像XY problem00/00/00 不是真正的有效日期。你为什么要解析它?为什么不直接检测它等于00/00/00 作为字符串然后使用预定值或行为呢?请解释问题的背景。
  • 不,这不是一个有效的日期。一个月没有第 0 年,没有第 0 个月,也没有第 0 天。 SimpleDateFormat 在宽松模式下(参见@MrSpoon 的评论)足够宽松,无论如何都可以解析它。
  • 正如上面的 cmets 已经说过的,这是不可能的。您可以做的最好的事情是检查String 是否为00/00/00 并单独处理 - 或尝试使用setLenient(false) 选项解析并捕获异常。

标签: java datetime datetime-parsing


【解决方案1】:

雨果已经说过了:

你能做的最好的就是检查String是否是00/00/00并处理它 单独 - 或尝试使用 setLenient(false) 选项和 捕获异常。

我想要在这里做的是向您展示如何跳过过时的(而且经常很麻烦)SimpleDateFormat 类,并使用现代 Java 日期和时间 API 遵循建议。

我首选的解决方案是明确检查日期字符串:

    if (dateFromFile.equals("00/00/00")) {
        System.out.println("0000-00-00");
    } else {
        System.out.println(LocalDate.parse(dateFromFile, 
                                           DateTimeFormatter.ofPattern("MM/dd/yy")));
    }

我假设您的字符串在 String dateFromFile 中。

另一种选择是尝试解析字符串并捕获异常(现代DateTimeFormatter 默认情况下并不宽松):

    try {
        System.out.println(LocalDate.parse(dateFromFile, 
                   DateTimeFormatter.ofPattern("MM/dd/yy")));
    } catch (DateTimeParseException dtpe) {
        System.out.println("0000-00-00");
    }

一个潜在的优势是它还可以捕获字符串包含未知字段的零但实际上不等于00/00/00 的情况——例如07/00/170/0/0

第三个也是最差的选项,从容地解析并与00/00/00出来的日期进行比较:

    DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("MM/dd/yy")
            .withResolverStyle(ResolverStyle.LENIENT);
    LocalDate unknownDateParsed = LocalDate.of(1999, Month.NOVEMBER, 30);
    LocalDate date = LocalDate.parse(dateFromFile, parseFormatter);
    if (date.equals(unknownDateParsed)) {
        System.out.println("0000-00-00");
    } else {
        System.out.println(date);
    }

DateTimeFormatter 假定为 2000–2099,当您给它一个两位数的年份时,00/00/00 变为 1999 年 11 月 30 日,因为它比 01/01/2000 早 1 个月 1 天。

最后一种方法的一个问题是验证效果较差:它会让其他不正确的日期(例如 05/35/1713/32/45)在没有通知的情况下通过。

【讨论】:

    【解决方案2】:

    将此类输入视为错误

    正如其他人所说,现代西方年表中没有零月或零日。

    因此,我会将此类输入视为错误条件,并拒绝该输入。

    DateTimeFormatter f = DateTimeFormatter. ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.US ) ;
    …
    
    if( input.equals( "00/00/00" ) ) { 
        … // handle error 
    } else {
        LocalDate ld = LocalDate.parse( input , f ) ; 
    }
    

    如果这是错误还是特殊值,您应该询问数据的来源。也许它是为了替代“空”类型的值,一个未知的日期。如果是这样,我会建议一个替代方案。例如,“未知”一词或指定的日期值。假设您的已知值较新,一个可能的此类值可能是 1970-01-01 的 common epoch reference date。对于日期时间,请使用常量 Instant.EPOCH 值 1970-01-01T00:00:00Z。

    【讨论】:

      猜你喜欢
      • 2018-01-06
      • 2011-03-07
      • 2012-07-16
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-25
      相关资源
      最近更新 更多