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

发布于 2024-08-18 21:27:16 字数 763 浏览 13 评论 0原文

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

不知何故,生产计算机上的日期格式与开发计算机上的格式不同。

格式化日期的代码是:

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”,一天后!

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

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


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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

兔姬 2024-08-25 21:27:16

我的第一个想法是这是一个并发问题。 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);
}

也有可能(但不太可能)在服务器。您是否记录了 getTimeZone() 中的值?

第三个选项是,套用 Inigo Montoya 的话,“您没有运行您希望的代码”认为你在跑步。”这可能是因为您的演示代码未在服务器上正确卸载,或者存在另一个日期格式化程序。

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.

二智少女猫性小仙女 2024-08-25 21:27:16

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

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?

梨涡 2024-08-25 21:27:16

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文