什么可能导致这个SimpleDateFormat格式错误?

时间:2010-01-21 18:35:49

标签: java date timezone simpledateformat

我有一个日期存储为数据库中的java.sql.Timestamp。日期为“2010-01-20T19:10:3​​5.000Z”,相当于1264014635743 ms。

不知何故,与开发机器相比,prod机器上的日期格式不同。

格式化日期的代码是:

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”!

当然,由于prod服务器上发生错误,我的调试选项有限......

我已经仔细检查了,两台服务器都有相同的时间和时区。两个时钟都与ntp服务器同步。


[更新] prod中的数据库具有以下值:“10-01-20 19:10:3​​5,743000000”作为日期字段

3 个答案:

答案 0 :(得分: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()

的值

第三个选项是,用Inigo Montoya来解释,“你没有运行你认为正在运行的代码。”可能是因为您的演示文稿代码没有在服务器上正确卸载,或者还有另一个日期格式化程序。

答案 1 :(得分:2)

虽然机器具有相同的时区,但数据库设置如何?是否可能将数据库设置为与计算机不同的时区?

答案 2 :(得分:0)

您是否检查过生产和开发机器上的JVM设置是否相同?时间可能在服务器级别同步,但可能JVM的设置方式对于它所在的时区有一些混淆。