Java 是什么导致此SimpleDataFormat格式错误?

Java 是什么导致此SimpleDataFormat格式错误?,java,date,timezone,simpledateformat,Java,Date,Timezone,Simpledateformat,我在数据库中有一个存储为java.sql.Timestamp的日期。日期为“2010-01-20T19:10:35.000Z”,相当于1264014635743毫秒 不知何故,prod机器上的日期格式与dev机器上的不同 设置日期格式的代码为: private final static String DATE_FORMAT = "yyyy-MM-dd"; public final static SimpleDateFormat APP_DATE_FORMATER = new SimpleDate

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

不知何故,prod机器上的日期格式与dev机器上的不同

设置日期格式的代码为:

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”。但在prod中我有“2010-01-21”,一天后

当然,由于错误发生在prod服务器上,我的调试选项受到限制

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



[更新]prod中的数据库的日期字段值为:“10-01-20 19:10:35743000000”

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

我的第一个想法是,这是一个并发问题
SimpleDataFormat
不是线程安全的,但您正在共享一个静态实例。如果需要在多线程环境中使用
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);
}
private static ThreadLocal\u datetimeFormatter=new ThreadLocal();
私有静态日期格式getDatetimeFormatter()
{
DateFormat=\u datetimeFormatter.get();
if(格式==null)
{
格式=新的简化格式(“yyyy-MM-dd'T'HH:MM:ss”);
format.setTimeZone(TimeZone.getTimeZone(“GMT”));
_datetimeFormatter.set(格式);
}
返回格式;
}
公共静态字符串formatDatetime(日期)
{
返回getDatetimeFormatter().format(日期);
}
也可能(但不太可能)在服务器上找不到“Etc/UTC”。您是否从
getTimeZone()
记录该值


第三种选择是,换言之,“您没有运行您认为正在运行的代码。”这可能是因为您的演示文稿代码没有在服务器上正确卸载,或者有另一个日期格式化程序在运行。

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

感谢线程化建议。但我怀疑问题的原因是线程问题,因为每次我刷新页面时,都会重新计算日期并显示为2010-01-21…在这种情况下,您看到的是时区问题。你能让系统管理员运行一个SSCEP来格式化和打印特定的时间戳值吗?我可以访问prod服务器,但我不知道“SSCEP”是什么(它是一台Windows server 2008机器)。我通过双击任务栏上的日期/时间来检查两台机器上的时区设置,它们是相同的。顺便说一句,谢谢你的本地代码!SSCEP是一个小型、自包含的示例程序。它应该是一个单独的类,包含原始帖子中的代码,并且只需格式化和打印已知的日期值。还可以为时区值添加打印语句。如果它能工作(正确设置日期格式),那么您就知道要查看代码中的其他地方(可能您有一些不使用日期格式的内容,或者使用了不同的格式)。如果它不起作用,您可以在不接触服务器代码的情况下找出原因。您可能还对我在博客上发布的一系列调试文章感兴趣: