SimpleDateFormat, возвращающий два разных результата для одного и того же ввода

1

Я получаю дату String от 02.04.201406: 26: 06, которую я конвертирую в другую дату

public static final SimpleDateFormat SDF_DATE_TIME_RECEIVED = new SimpleDateFormat("dd-MM-yy HH:mm:ss");
static{
    SDF_DATE_TIME_RECEIVED.setTimeZone(TimeZone.getTimeZone("IST"));
}
SimpleDateFormat originalDateFormat = new SimpleDateFormat("dd.MM.yyyyHH:mm:ss");
originalDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
Date date = originalDateFormat.parse(dateString);
String newDateString = SDF_DATE_TIME_RECEIVED.format(date));

Это выполняется правильно и дает мне дату 02-04-14 11:56:06

Теперь я использую этот newDateString для создания двух разных форматов, как показано ниже:

SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yy");
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
Date date = SDF_DATE_TIME_RECEIVED.parse(newDateString);
String datePart = dateFormat.format(date);
String timePart = timeFormat.format(date);

Теперь проблема заключается в том, что на сервере Production для dateString, упомянутом выше, я получил результат как:

newDateString = "04/02/2014 11:56:06"
datePart = "04/02/70"
timePart = "00:56:06"

Я попытался воссоздать сценарий в среде dev, но получил правильные результаты:

newDateString = "04/02/2014 11:56:06"
datePart = "04/02/14"
timePart = "11:56:06"

Даже при выполнении одного и того же процесса в производственной среде путем повторной отправки запроса появляется правильный вывод.

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

  • 2
    Какой часовой пояс по умолчанию для Dev и Production? Кроме того, SimpleDateFormat не является потокобезопасным, поэтому не следует создавать статические экземпляры, если они могут использоваться в многопоточной среде.
  • 1
    Попробуйте изолировать, является ли это анализом или форматированием. Вы делаете две операции разбора и три операции форматирования - если вы можете исправить это на new Date(SOME_CONSTANT_LONG_VALUE); String text = format.format(date); и все же покажите несоответствие, это поможет вам намного легче помочь. Также обратите внимание, что вы не устанавливаете часовой пояс в dateFormat и timeFormat , поэтому вы получите системный часовой пояс по умолчанию. (Вы можете даже получить системный календарь по умолчанию - я не уверен.) Наконец, SimpleFormat не является потокобезопасным ...
Показать ещё 3 комментария
Теги:
date-format
simpledateformat

1 ответ

1
Лучший ответ

Internally SimpleDateFormat имеет статус stateful, поэтому статический final не помогает вообще с проблемой многопоточности. Если ваш код вызывается несколькими запросами, SDF_DATE_TIME_RECEIVED даст коррумпированные результаты. Это первый подозреваемый в этой проблеме (тем более, что ошибки кажутся случайными), попробуйте изменить его на локальную переменную.

Другая идея: вы не устанавливали никаких часовых поясов в dateFormat и timeFormat. Похоже, вы ожидаете, что это индийское стандартное время (IST), чтобы вы это сделали:

public static void main(String[] args) throws Exception {

    SimpleDateFormat SDF_DATE_TIME_RECEIVED = new SimpleDateFormat("dd-MM-yy HH:mm:ss");
    SDF_DATE_TIME_RECEIVED.setTimeZone(TimeZone.getTimeZone("IST"));

    SimpleDateFormat originalDateFormat = new SimpleDateFormat("dd.MM.yyyyHH:mm:ss");
    originalDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));

    String dateString = "02.04.201406:26:06";
    Date date1 = originalDateFormat.parse(dateString);
    String newDateString = SDF_DATE_TIME_RECEIVED.format(date1);

    System.out.println(newDateString);

    SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yy");
    dateFormat.setTimeZone(TimeZone.getTimeZone("IST"));
    SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
    timeFormat.setTimeZone(TimeZone.getTimeZone("IST"));

    Date date2 = SDF_DATE_TIME_RECEIVED.parse(newDateString);
    String datePart = dateFormat.format(date2);
    String timePart = timeFormat.format(date2);

    System.out.println("datePart=" + datePart);
    System.out.println("timePart=" + timePart);
}
  • 0
    Я приму этот ответ, если он работает ... делать тестирование ....
  • 2
    Кстати, IST означает индийское стандартное время :)
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню