使用SimpleDateFormat.parse()解析日期时出现NumberFormatException

彼得

具有创建仅时间Date对象的函数。(为什么需要这样做是一个长话短说,在这种情况下是无关紧要的,但是我需要与XML世界中的一些东西进行比较,其中TIME(即仅时间)是一个有效的概念)。

private static final SimpleDateFormat DF_TIMEONLY = new SimpleDateFormat("HH:mm:ss.SSSZ");    

public static Date getCurrentTimeOnly() {

    String onlyTimeStr = DF_TIMEONLY.format(new Date());  // line #5
    Date  onlyTimeDt = null;
    try {
        onlyTimeDt = DF_TIMEONLY.parse(onlyTimeStr);  // line #8
    } catch (ParseException ex) { 
        // can never happen (you would think!)
    }
    return onlyTimeDt;
}

可能至少还有其他几种方法可以在Java中创建纯时间日期(或更确切地说,日期部分为1970-01-01的日期),但我的问题实际上不是关于此的。

我的问题是,这段代码在生产中运行了很长时间之后,开始在第8行随机抛出NumberFormatException从技术上讲,我应该说这是不可能的,对吧?

这是上面代码的一部分随机NumberFormatExceptions的摘录:

java.lang.NumberFormatException: multiple points
java.lang.NumberFormatException: For input string: ".11331133EE22"
java.lang.NumberFormatException: For input string: "880044E.3880044"
java.lang.NumberFormatException: For input string: "880044E.3880044E3"

首先,我希望我们可以同意,正式地这应该是不可能的吗?代码使用相同的格式(DF_TIMEONLY)作为输出,然后输入。如果您不同意这不可能,请告诉我。

我无法在独立环境中重现该问题。当JVM运行了很长时间(> 1周)时,似乎出现了问题。我找不到问题的模式,例如夏令时/冬令时,AM / PM等。该错误是零星的,这意味着一分钟它将抛出NumberFormatException,而下一分钟它将正常运行。

我怀疑在JVM甚至CPU中都会存在某种算术故障。上述例外情况表明其中涉及浮点数,但我看不到它们的来源。据我所知,Java的Date对象是一个包装器,用于包装long自时代以来的毫秒数。

我猜正在发生的是onlyTimeStr在第5行中创建了一个意外的字符串,因此问题确实出在这里,而不是在第8行中。

这是完整堆栈跟踪的示例:

java.lang.NumberFormatException: For input string: "880044E.3880044E3"
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
    at java.lang.Double.parseDouble(Double.java:540)
    at java.text.DigitList.getDouble(DigitList.java:168)
    at java.text.DecimalFormat.parse(DecimalFormat.java:1321)
    at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2086)
    at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1455)
    at java.text.DateFormat.parse(DateFormat.java:355)
    at org.mannmann.zip.Tanker.getCurrentTimeOnly(Tanker.java:746)

环境:Java 7

发条缪斯

可能的原因是SimpleDateFormat不是线程安全的事实,并且您正在从多个线程中引用它。虽然极其困难的证明(约一样难以测试),有一些证据是这种情况:

  1. .11331133EE22 -注意一切都翻了一番
  2. 880044E.3880044E3 - 同样在这里

您可能至少有两个线程交织。E让我感到困惑,我认为它正在尝试处理科学计数法(例如1E10等),但这可能是时区的一部分

幸运的是,(格式化)基本修复很简单:

private static final String FORMAT_STRING = "HH:mm:ss.SSSZ";    

public static Date getCurrentTimeOnly() {

    SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_STRING);

    String onlyTimeStr = formatter.format(new Date());
    return formatter.parse(onlyTimeStr);
}

您还可以在这里做其他几件事,但要注意以下几点:

1-如果时区为UTC(或任何不带DST的时区),那么这是微不足道的

public static Date getCurrentTimeOnly() {

    Date time = new Date();

    time.setTime(time.getTime() % (24 * 60 * 60 * 1000));

    return time;
}

2-您将无法测试此方法,因为您不能安全地暂停时钟(可以更改时区/语言环境)。为了更好地处理Java中的日期/时间,请使用JodaTime之类的东西请注意,LocalTime它没有附加时区,而Date仅以整数小时返回偏移量(并且存在不在hour上的时区);为了安全起见,您需要返回一个Calendar(带有完整时区),或者只返回没有它的东西:

// This method is now more testable.  Note this is only safe for non-DST zones
public static Calendar getCurrentTimeOnly() {

    Calendar cal = new Calendar();

    // DateTimeUtils is part of JodaTime, and is a class allowing you to pause time!
    cal.setTimeInMillis(DateTimeUtils.currentTimeMillis() % (24 * 60 * 60 * 1000));

    return cal;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用SimpleDateFormat无法解析的日期

来自分类Dev

使用SimpleDateFormat的日期差

来自分类Dev

使用SimpleDateFormat.parse时出现错误的月份

来自分类Dev

Java无法使用SimpleDateFormat解析UTC日期

来自分类Dev

使用 SimpleDateFormat Android 的不可解析日期

来自分类Dev

在SimpleDateFormat#parse()中使用〜

来自分类Dev

使用SimpleDateFormat以UTC获取日期

来自分类Dev

使用SimpleDateFormat解析10 ^ -7

来自分类Dev

使用SimpleDateFormat时发生ParseException

来自分类Dev

SimpleDateFormat无法解析的日期:使用解析方法时为“ 7月7日”

来自分类Dev

SimpleDateFormat无法解析的日期:使用解析方法时为“ 7月7日”

来自分类Dev

如何使用SimpleDateFormat格式化日期

来自分类Dev

如何使用 SimpleDateFormat 获取所需的日期格式

来自分类Dev

使用AM / PM的SimpleDateFormat解析错误

来自分类Dev

使用SimpleDateFormat.java解析时区

来自分类Dev

使用SimpleDateFormat解析svn log -xml日期输出

来自分类Dev

无法在Java / scala中使用SimpleDateFormat解析日期

来自分类Dev

使用SimpleDateFormat的另一个无法解析的日期

来自分类Dev

使用SimpleDateFormat解析svn log -xml日期输出

来自分类Dev

无法使用 SimpleDateFormat 解析字符串日期

来自分类Dev

使用 SimpleDateFormat 格式化日期时抛出 ClassCastException

来自分类Dev

使用SimpleDateFormat格式化不同本地人的日期

来自分类Dev

使用SimpleDateFormat将字符串转换为日期

来自分类Dev

如何使用simpledateformat将字符串转换为日期

来自分类Dev

使用 SimpleDateFormat(string,locale) 解析法语语言环境的错误

来自分类Dev

如何使用 SimpleDateFormat.parse() 将 Calendar.toString() 转换为日期?

来自分类Dev

使用SimpleDateFormat将字符串解析为日期,毫秒数变化

来自分类Dev

如何在没有ParseException的情况下使用SimpleDateFormat测试解析日期

来自分类Dev

Java的无法解析日期的SimpleDateFormat

Related 相关文章

  1. 1

    使用SimpleDateFormat无法解析的日期

  2. 2

    使用SimpleDateFormat的日期差

  3. 3

    使用SimpleDateFormat.parse时出现错误的月份

  4. 4

    Java无法使用SimpleDateFormat解析UTC日期

  5. 5

    使用 SimpleDateFormat Android 的不可解析日期

  6. 6

    在SimpleDateFormat#parse()中使用〜

  7. 7

    使用SimpleDateFormat以UTC获取日期

  8. 8

    使用SimpleDateFormat解析10 ^ -7

  9. 9

    使用SimpleDateFormat时发生ParseException

  10. 10

    SimpleDateFormat无法解析的日期:使用解析方法时为“ 7月7日”

  11. 11

    SimpleDateFormat无法解析的日期:使用解析方法时为“ 7月7日”

  12. 12

    如何使用SimpleDateFormat格式化日期

  13. 13

    如何使用 SimpleDateFormat 获取所需的日期格式

  14. 14

    使用AM / PM的SimpleDateFormat解析错误

  15. 15

    使用SimpleDateFormat.java解析时区

  16. 16

    使用SimpleDateFormat解析svn log -xml日期输出

  17. 17

    无法在Java / scala中使用SimpleDateFormat解析日期

  18. 18

    使用SimpleDateFormat的另一个无法解析的日期

  19. 19

    使用SimpleDateFormat解析svn log -xml日期输出

  20. 20

    无法使用 SimpleDateFormat 解析字符串日期

  21. 21

    使用 SimpleDateFormat 格式化日期时抛出 ClassCastException

  22. 22

    使用SimpleDateFormat格式化不同本地人的日期

  23. 23

    使用SimpleDateFormat将字符串转换为日期

  24. 24

    如何使用simpledateformat将字符串转换为日期

  25. 25

    使用 SimpleDateFormat(string,locale) 解析法语语言环境的错误

  26. 26

    如何使用 SimpleDateFormat.parse() 将 Calendar.toString() 转换为日期?

  27. 27

    使用SimpleDateFormat将字符串解析为日期,毫秒数变化

  28. 28

    如何在没有ParseException的情况下使用SimpleDateFormat测试解析日期

  29. 29

    Java的无法解析日期的SimpleDateFormat

热门标签

归档