以Java代码返回NumberFormatException形式的SimpleDateFormat 使用java.time

问题描述

我已经在常量文件中声明了SimpleDateFormat对象为静态字段,如下所示,

Constants.java

public static final SimpleDateFormat GENERAL_TZ_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");

在我的类文件中,我的实现是这样的。

String fDate = getTextValue(empNo,"firstDate");
if (null != fDate && !fDate.isEmpty()) {
    try {
        Date date = (Date)(Constants.GENERAL_TZ_FORMATTER).parse(fDate);
        issue.setDate(date.getTime());
    } catch (ParseException e) {
        logUtil.error(LOG,e+ "date : " + date);
    }
}

错误:

Exception while importing data. package name.SecureException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

我的问题是,在某些情况下,这会抛出NumberFormatException(非常罕见的情况),因此我一直想知道自己做了诊断,并且大多数人都在解释这种情况可能会发生由于SimpleDateFormat不是线程安全的。如果是这种情况,我不清楚此代码如何在不使用多个线程的情况下在多线程环境中运行,是否会使DateFormat.parse()的输入为空字符串?

Java's SimpleDateFormat is not thread-safe article

我已尝试解决此问题,但是要重现此问题确实非常困难,我想了解您对此的想法,这将有助于我找到更好的解决方案。非常感谢您的建议。 谢谢。

解决方法

好吧,正如您的帖子下方的评论已经提到的那样,您无论如何都不应该使用SimpleDateFormat

您可能偶然发现了SimpleDateFormat麻烦的情况。但是,这不是唯一的原因。 This Stackoverflow post explains why太麻烦了。在同一篇文章中提到SimpleDateFormat不是线程安全的原因之一。线程安全性是,当多个进程作用于格式化程序时,即利用格式化程序来格式化日期,并且不会由于干扰而发生不正确,不准确或不确定的结果。

Your link to the article on Callicoder很好地解释了为什么 SimpleDateFormat引起麻烦。帖子中提到的异常与您一样:

java.lang.NumberFormatException: For input string: ""

简而言之,线程在使用格式化程序时会发生干扰,因为格式化程序未同步。这意味着SimpleDateFormat类不会强制一个线程必须等到另一个线程完成其内部状态修改后再执行。使用的三个类是SimpleDateFormatDateFormatFieldPosition

TryItOnline!Here's erroneous code in action

使用java.time

您需要转到java.time软件包中可用的较新的Java 8 Date and Time API。由于它们的不变性,它们绝对是线程安全的。在您的情况下,请使用java.time.format.DateTimeFormatter

public static final DateTimeFormatter GENERAL_TZ_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
ZonedDateTime zdt = ZonedDateTime.parse(fDate,GENERAL_TZ_FORMATTER);
Instant instant = zdt.toInstant();

// Your setDate should really accept an Instant:
issue.setDate(instant);
// If that's REALLY not possible,then you can convert it to an integer
// value equal to the number of milliseconds since 1 January 1970,midnight
//issue.setDate(instant.toEpochMilli());

相关问答

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