SimpleDateFormat 显示不一致的结果

SimpleDateFormat showing inconsistent results

val dateStr = "2020 10 12 23 12 13"
val dateFormat = "yyyyMMddHHmmss"
import java.util.Date
val sdf = new SimpleDateFormat(dateFormat)
sdf.setLenient(false)
val res = sdf.parse(dateStr)
println("res = "+res)

scala> val res = sdf.parse(dateStr)
java.text.ParseException: Unparseable date: "2020 10 12 23 12 13"
  at java.text.DateFormat.parse(DateFormat.java:366)
  ... 50 elided

上面的代码块解析并导致异常,但如果我将“MM”部分从“10”更改为“11”,那么它解析正常,没有任何异常,但日期错误。知道为什么吗? 如果我的日期字符串不是这种格式“yyyyMMddHHmmss”

,我希望代码失败或抛出异常
/*Note the 11 instead of 10*/
    val dateStr = "2020 11 12 23 12 13"
    val dateFormat = "yyyyMMddHHmmss"
    import java.util.Date
    val sdf = new SimpleDateFormat(dateFormat)
    sdf.setLenient(false)
    val res = sdf.parse(dateStr)
    println("res = "+res)
    
    
    scala> val res = sdf.parse(dateStr)
    res: java.util.Date = Wed Jan 01 01:02:23 PST 2020

您好,我认为问题出在日期格式上:

    val dateFormat = "yyyyMMddHHmmss"

应该是

    val dateFormat = "yyyy MM dd HH mm ss"

因为您的 dateStr 包含一些 space 在格式中发挥重要作用的人

但是如果你想失败以防你有 space 或日期中不需要的其他东西,也许正则表达式是最好的答案?

正确,您的格式与输入数据不匹配。

java.time

更重要的是,你用错了类。与最早版本的 Java 捆绑在一起的日期时间 类 很糟糕。多年前,它们被 JSR 310 中定义的现代 java.time 类 所取代。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu MM dd HH mm ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

要检测错误输入,陷阱 DateTimeParseException

try
{
    LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
}
catch ( DateTimeParseException e ) 
{
    …
}

ResolverStyle

DateTimeFormatter 使用三种不同的解析方法之一:严格、智能和宽松。这些由 ResolverStyle 枚举表示。默认使用 SMART,但如果更适合您的需要,您可以指定 STRICT

ISO 8601

我建议您就 ISO 8601 对输入数据的发布者进行培训。该标准定义了以文本方式交换日期时间值的格式。

java.time类在parsing/generating字符串时默认使用ISO 8601格式。因此无需为合规输入定义格式化模式。

SimpleDateFormat 对于您想要的东西来说太宽松了。 它将您的日期解析为:

2020 yyyy
_1   MM (where _ represents a space)
1    dd
_1   HH
2    mm
23   seconds
12 13 ignored

所以我认为最好的解决方法是硬着头皮禁止空格。

因此请尝试修剪字符串,然后在中间搜索空格。如果找到空格,则抛出异常。

但最终最好放弃 SimpleDateFormat 并使用新的东西。我认为新的 DateTimeFormatter class 会更好地为您服务:

// In Java
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
LocalDateTime date = LocalDateTime.parse(dateStr, formatter);
System.out.println("date="+date);

这会引发异常。

在 Scala 中:

val formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
val date = LocalDateTime.parse(dateStr, formatter);
println("date="+date);