2

データベースに java.sql.Timestamp として日付を保存しています。日付は「2010-01-20T19:10:35.000Z」で、1264014635743 ミリ秒に相当します。

どういうわけか、日付は開発マシンと比較して製品マシンで異なる形式になっています。

日付をフォーマットするコードは次のとおりです。

private final static String DATE_FORMAT = "yyyy-MM-dd";
public final static SimpleDateFormat APP_DATE_FORMATER = new SimpleDateFormat(DATE_FORMAT);
private static final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("Etc/UTC");
APP_DATE_FORMATER.setTimeZone(UTC_TIMEZONE);
DateTimeZone.setDefault(DateTimeZone.UTC);

String output = APP_DATE_FORMATER.format(date)

dev で生成された出力は、正しい "2010-01-20" です。しかし、製品には「2010-01-21」があり、1日後です!

もちろん、prodサーバーでエラーが発生するため、デバッグオプションは限られています...

再確認しましたが、両方のサーバーの時刻とタイムゾーンが同じです。両方のクロックは ntp サーバーと同期されます。


[更新] prod のデータベースの値は、日付フィールドの「10-01-20 19:10:35,743000000」です。

4

3 に答える 3

4

私の最初の考えは、これは並行性の問題であるということです。SimpleDateFormatスレッドセーフではありませんが、静的インスタンスを共有しています。java.textマルチスレッド環境でフォーマッターを使用する必要がある場合は、ThreadLocalを使用してフォーマッターを保持する必要があります。

private static ThreadLocal<DateFormat> _datetimeFormatter = new ThreadLocal<DateFormat>();

private static DateFormat getDatetimeFormatter()
{
    DateFormat format = _datetimeFormatter.get();
    if (format == null)
    {
        format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        _datetimeFormatter.set(format);
    }
    return format;
}

public static String formatDatetime(Date date)
{
    return getDatetimeFormatter().format(date);
}

「Etc/UTC」がサーバー上に見つからない可能性もあります(ただし、可能性は低いです)。から値をログに記録しますgetTimeZone()か?

そして3番目のオプションは、Inigo Montoyaを言い換えると、「実行していると思われるコードを実行していない」ということです。プレゼンテーションコードがサーバーに適切にアンロードされなかったか、別の日付フォーマッターが浮かんでいることが原因である可能性があります。

于 2010-01-21T18:43:15.530 に答える
2

マシンのタイム ゾーンは同じですが、データベースの設定はどうでしょうか。データベースがマシンとは異なるタイムゾーンに設定されている可能性はありますか?

于 2010-01-21T18:41:04.910 に答える
0

JVM 設定が本番マシンと開発マシンで同じであることを確認しましたか? 時刻はサーバー レベルで同期している可能性がありますが、JVM の設定方法により、JVM がどのタイム ゾーンにあるかについて混乱が生じている可能性があります。

于 2010-01-21T18:48:11.717 に答える