我正在尝试将字符串解析为对象构造函数中的日期,我们将其称为Example
。这是代码
private static final SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
private long time;
public Example(String date) {
try {
this.time = sdf.parse(date).getTime();
} catch (Exception e) {
logger.log(Level.WARNING, "Exception while parsing date " + date, e);
}
}
现在,我在Tomcat实例中创建这些对象(无论是否有所不同)。
我得到以下类型的例外
Fri Jul 06 15:13:48 EDT 2012 WARNING: Exception while parsing date 2012-07-06 18:57:31
java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Long.parseLong(Long.java:431)
at java.lang.Long.parseLong(Long.java:468)
at java.text.DigitList.getLong(DigitList.java:177)
at java.text.DecimalFormat.parse(DecimalFormat.java:1297)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1589)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311)
at java.text.DateFormat.parse(DateFormat.java:335)
at ...
Fri Jul 06 15:13:48 EDT 2012 WARNING: Exception while parsing date 2012-07-06 19:00:07
java.lang.NumberFormatException: multiple points
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1082)
at java.lang.Double.parseDouble(Double.java:510)
at java.text.DigitList.getDouble(DigitList.java:151)
at java.text.DecimalFormat.parse(DecimalFormat.java:1302)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1934)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311)
at java.text.DateFormat.parse(DateFormat.java:335)
at ...
Fri Jul 06 15:13:48 EDT 2012 WARNING: Exception while parsing date 2012-07-06 19:13:21
java.lang.ArrayIndexOutOfBoundsException: -1
at java.text.DigitList.fitsIntoLong(DigitList.java:212)
at java.text.DecimalFormat.parse(DecimalFormat.java:1295)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1934)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311)
at java.text.DateFormat.parse(DateFormat.java:335)
at ...
Fri Jul 06 15:48:06 EDT 2012 WARNING: Exception while parsing last check string 2012-07-06 19:08:08
java.lang.NumberFormatException: For input string: ".200172E4.200172"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1222)
at java.lang.Double.parseDouble(Double.java:510)
at java.text.DigitList.getDouble(DigitList.java:151)
at java.text.DecimalFormat.parse(DecimalFormat.java:1302)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1589)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311)
at java.text.DateFormat.parse(DateFormat.java:335)
at ...
因此日期
失败2012-07-06 18:57:31
2012-07-06 19:00:07
2012-07-06 19:13:21
2012-07-06 19:08:08
但是,如果我进行单元测试,我会从这些字符串中获取time
的以下值
1341615451000
1341615607000
1341616401000
1341616088000
所以SimpleDateFormat
对象确实有用......但不在服务器上?我注意到这个问题发生在服务器启动附近,然后不再发生,如果这有帮助的话。不确定下一步该怎么做。
使用Tomcat 7.0和Java 1.6更新32。
答案 0 :(得分:38)
SimpleDateFormat不是线程安全的,如https://www.palantir.com/2007/07/simpledateformat-is-not-thread-safe/所述 有时,使用“静态”对象时真正奇怪或非逻辑的行为来自并发问题
要解决这种情况,每次都要使用一个新实例(它比同步更好,因为同步会引发瓶颈问题)
答案 1 :(得分:4)
SimpleDateFormat不是线程安全的:请参阅Javadoc。
答案 2 :(得分:1)
从Java 8+开始,最好选择基于java.time
的解决方案。
java.time
中的类线程安全。
您可以像这样实现等效日期提取:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
...
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime date = LocalDateTime.parse(str, dockerDateFormatter);
然后从date
查询所需的字段。
DateTimeFormatter和LocalDateTime的JavaDoc中的更多详细信息。
另一个TLDR resource有两个现成的例子。