Java DateFormat parse () не поддерживает часовой пояс - PullRequest
14 голосов
/ 23 сентября 2011
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("America/New_York"));

try {
    System.out.println(df.format(cal.getTime()));
    System.out.println(df.parse(df.format(cal.getTime())));
} catch (ParseException e) {
    e.printStackTrace();
}

Вот результат:

2011-09-24 14:10:51 -0400

Сб 24 сентября 20:10:51 CEST 2011

Почему, когда я анализирую дату, полученную из format (), она не учитывает часовой пояс?

Ответы [ 3 ]

23 голосов
/ 23 сентября 2011

Вы печатаете результат вызова Date.toString(), который всегда использует часовой пояс по умолчанию. По сути, вы не должны использовать Date.toString() ни для чего, кроме отладки.

Не забывайте, что Date не имеет часовой пояс - он представляет момент времени, измеряемый в миллисекундах с эпохи Unix (полночь 1 января 1970 года по Гринвичу).

Если вы снова форматируете дату, используя ваш форматер, , что должен дать тот же ответ, что и раньше.

Кроме того, я бы рекомендовал использовать Joda Time вместо Date / Calendar, если вы выполняете сколько-нибудь значительную работу с датой / временем на Java; это намного приятнее API.

7 голосов
/ 28 сентября 2012

DateFormat.parse() НЕ является запросом (что-то, что возвращает значение и не меняет состояние системы). Это команда, которая имеет побочный эффект обновления внутреннего Calendar объекта. После вызова parse() вы должны получить доступ к часовому поясу, либо набрав DateFormat Calendar, либо позвонив по номеру DateFormat.getTimeZone(). Если вы не хотите выбросить исходный часовой пояс и использовать местное время, не используйте возвращенное значение Date из parse(). Вместо этого используйте объект календаря после разбора. И то же самое верно для метода форматирования. Если вы собираетесь отформатировать дату, перед вызовом format() передайте календарь с информацией о часовом поясе в объект DateFormat. Вот как вы можете преобразовать один формат в другой, сохранив исходный часовой пояс:

    DateFormat originalDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
    DateFormat targetDateFormat = new SimpleDateFormat("EEE., MMM. dd, yyyy");

    originalDateFormat.parse(origDateString);
    targetDateFormat.setCalendar(originalDateFormat.getCalendar());
    return targetDateFormat.format(targetDateFormat.getCalendar().getTime());

Это грязно, но необходимо, поскольку parse() не возвращает значение, которое сохраняет часовой пояс, а format() не принимает значение, которое определяет часовой пояс (класс Date).

2 голосов
/ 23 сентября 2011

DateFormat - это абстрактный класс для подклассов форматирования даты / времени, который форматирует и анализирует даты или время независимо от языка.Подкласс форматирования даты / времени, такой как SimpleDateFormat, позволяет форматировать (например, дата -> текст), анализировать (текст -> дата) и нормализовать. Дата представляется в виде объекта Date или в миллисекундах с 1 января 1970 г., 00:00:00 GMT .

Из spec ,возвращаемое время эпохи

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...