Что может вызвать эту ошибку форматирования SimpleDateFormat?

StackOverflow https://stackoverflow.com/questions/2111852

Вопрос

У меня есть дата, сохраненная в виде метки 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:35,743000000" для поля даты

Это было полезно?

Решение

Моя первая мысль заключается в том, что это проблема параллелизма. 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()?

И третий вариант, перефразируя Иниго Монтойя, "вы запускаете не тот код, который, по вашему мнению, вы запускаете". Это может быть потому, что ваш код презентации неправильно выгрузился на сервер, или есть другой форматировщик даты, плавающий вокруг.

Другие советы

Хотя компьютеры имеют один и тот же часовой пояс, как насчет настроек базы данных?Возможно ли, что база данных настроена на другой часовой пояс, чем компьютер?

Вы проверили, что настройки JVM одинаковы на компьютерах производства и разработки?Время может быть синхронизировано на уровне сервера, но, возможно, способ настройки JVM приводит к некоторой путанице в отношении того, в каком часовом поясе он находится.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top