20

オブジェクトのコンストラクターで文字列を日付に解析しようとしています。これを呼び出します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オブジェクトは機能します...しかし、サーバー上では機能しませんか?この問題はサーバーの起動の近くで発生しますが、それが役に立ったとしても、後で発生することはありません。次に何をすべきかよくわかりません。

Tomcat7.0およびJava1.6アップデート32を使用します。

4

3 に答える 3

41

説明されているように、SimpleDateFormatはスレッドセーフではありませんhttps://www.palantir.com/2007/07/simpledateformat-is-not-thread-safe/ 時々、「静的」オブジェクトを使用するときの本当に奇妙なまたは非論理的な動作は、並行性に起因します問題

このような場合を解決するには、毎回新しいインスタンスを使用します(同期するとボトルネックの問題が発生する可能性があるため、同期するよりも優れています)

于 2012-07-08T18:22:25.820 に答える
4

SimpleDateFormatはスレッドセーフではありません。Javadocを参照してください。

于 2012-07-07T03:00:42.750 に答える
2

java.timeJava 8以降では、ベースのソリューションを選択する方がよい場合があります。

のクラス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

詳細については、JavaDocforDateTimeFormatterおよびLocalDateTimeを参照ください

2つのすぐに使用できる例を含む別のTLDRリソース

于 2017-05-17T17:12:51.300 に答える