Что может вызвать эту ошибку форматирования SimpleDateFormat? - PullRequest
2 голосов
/ 21 января 2010

У меня дата хранится в виде 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". Но в прод у меня "2010-01-21", через день!

Конечно, поскольку ошибка возникает на сервере prod, я ограничен в своих возможностях отладки ...

Я дважды проверил, и оба сервера имеют одинаковое время и часовой пояс. Обе часы синхронизируются с NTP-сервером.


[ОБНОВЛЕНИЕ] База данных в prod имеет значение: «10-01-20 19: 10: 35,743000000» для поля даты

Ответы [ 3 ]

4 голосов
/ 21 января 2010

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

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

2 голосов
/ 21 января 2010

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

0 голосов
/ 21 января 2010

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

...