开发者

What could cause this SimpleDateFormat formatting error?

I have a date stored as a java.sql.Timestamp in a database. The date is "2010-01-20T19:10:35.000Z" and is equivalent to 1264014635743 ms.

Somehow, the date is formatted differently on the prod machine compared to the dev machine.

The code to format the date is:

private final static String DATE_FORMAT = "yyyy-MM-dd";
publ开发者_如何转开发ic 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)

The generated output in dev is the correct "2010-01-20". But in prod I have "2010-01-21", one day later!

Of course, since the error occurs on the prod server, I'm limited in my debugging options...

I have double checked, and both server have the same time and timezone. Both clock are synchronized with an ntp server.


[UPDATE] The database in prod has the value: "10-01-20 19:10:35,743000000" for the date field


My first thought is that this is a concurrency issue. SimpleDateFormat is not thread-safe, yet you're sharing a static instance. If you need to use java.text formatters in a multi-threaded environment, you should use a ThreadLocal to hold them:

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);
}

It's also possible (but unlikely) that "Etc/UTC" is not found on the server. Do you log the value from getTimeZone()?

And the third option is, to paraphrase Inigo Montoya, "you are not running the code that you think that you are running." It could be because your presentation code didn't properly unload on the server, or there's another date formatter floating around.


While the machines have the same time zone, what about database settings? Is it possible that the database is set to a different time zone than the machine?


Have you checked that the JVM settings are the same on the Production and Development machines? The times may be in sync at the server level, but maybe the way the JVM is set up is has some confusion about what time zone it is in.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜