Java 是什么导致此SimpleDataFormat格式错误?
我在数据库中有一个存储为java.sql.Timestamp的日期。日期为“2010-01-20T19:10:35.000Z”,相当于1264014635743毫秒 不知何故,prod机器上的日期格式与dev机器上的不同 设置日期格式的代码为: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
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是一个小型、自包含的示例程序。它应该是一个单独的类,包含原始帖子中的代码,并且只需格式化和打印已知的日期值。还可以为时区值添加打印语句。如果它能工作(正确设置日期格式),那么您就知道要查看代码中的其他地方(可能您有一些不使用日期格式的内容,或者使用了不同的格式)。如果它不起作用,您可以在不接触服务器代码的情况下找出原因。您可能还对我在博客上发布的一系列调试文章感兴趣: