我有一个日期存储为数据库中的java.sql.Timestamp。日期为“2010-01-20T19:10:35.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:35,743000000”作为日期字段
答案 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的设置方式对于它所在的时区有一些混淆。