Как отобразить дату с пользовательским часовым поясом?

Допустим, у меня есть строка, представляющая дату, которая выглядит так:

«Среда, 08 июля, 17:08:48 по Гринвичу 2009 г.»

Итак, я разбираю эту строку в объект даты следующим образом:

DateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZ yyyy");
Date fromDate = (Date)formatter.parse(fromDateString);

Это дает мне правильный объект даты. Теперь я хочу отобразить эту дату как значение CDT.

Я пробовал много вещей, и я просто не могу заставить его работать правильно. Должен быть простой метод, использующий класс DateFormat, чтобы заставить это работать. Любой совет? Моя последняя попытка была такой:

formatter.setTimeZone(toTimeZone);
String result = formatter.format(fromDate);

person Kyle Boon    schedule 22.07.2009    source источник


Ответы (4)


Используйте «zzz» вместо «ZZZ»: «Z» — это символ часового пояса RFC822.

DateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");

Сказав это, мой стандартный совет по дате/времени — использовать Joda Time, что в целом лучше API.

РЕДАКТИРОВАТЬ: короткая, но полная программа:

import java.text.*;
import java.util.*;

public class Test
{
    public List<String> names;

    public static void main(String [] args)
        throws Exception // Just for simplicity!
    {
        String fromDateString = "Wed Jul 08 17:08:48 GMT 2009";
        DateFormat formatter = new SimpleDateFormat
            ("EEE MMM dd HH:mm:ss zzz yyyy");
        Date fromDate = (Date)formatter.parse(fromDateString);
        TimeZone central = TimeZone.getTimeZone("America/Chicago");
        formatter.setTimeZone(central);
        System.out.println(formatter.format(fromDate));
    }
}

Вывод: среда, 08 июля, 12:08:48 CDT 2009

person Jon Skeet    schedule 22.07.2009
comment
К сожалению, я не могу добавить еще одну зависимость без дополнительных бюрократических проволочек, с которыми я хочу иметь дело. Должен быть способ отформатировать часовые пояса с помощью стандартных библиотек Java. - person Kyle Boon; 22.07.2009
comment
Есть, как указано в ответе. Просто ожидайте большей боли, если вам нужно выполнить какие-либо другие манипуляции с датой/временем. - person Jon Skeet; 22.07.2009
comment
Это не помогает. Средство форматирования всегда выдает время по Гринвичу, а не по запрошенному CDT. - person Kyle Boon; 22.07.2009
comment
Тогда вы используете неправильный часовой пояс — в моем тестовом примере это сработало нормально. Я добавлю короткую, но полную программу для демонстрации. - person Jon Skeet; 22.07.2009
comment
Да, ты был прав... чувак, это боль. Все время был правильный код, и опечатка в моем модульном тесте не позволила ему работать правильно. - person Kyle Boon; 28.07.2009

С использованием:

formatter.setTimeZone(TimeZone.getTimeZone("US/Central"));

выходы:

Wed Jul 08 12:08:48 CDT 2009

на дату в вашем примере на моей машине. То есть после замены ZZZ на ZZZ в строке формата.

person laz    schedule 22.07.2009

Извините, что откопал старую тему. Но мне было интересно, есть ли java-класс, который содержит все идентификаторы часовых поясов как постоянный класс. Таким образом, вместо того, чтобы жестко кодировать идентификатор часового пояса при установке часового пояса следующим образом:

formatter.setTimeZone(TimeZone.getTimeZone("US/Central"));

вместо этого мы будем делать что-то более стандартное/однородное:

formatter.setTimeZone(TimeZone.getTimeZone(SomeConstantClass.US_CENTRAL)); 

где SomeConstantClass.java — это класс, который содержит константы, относящиеся к различным идентификаторам часовых поясов, которые поддерживаются классом TimeZone.

person hipsandy    schedule 09.05.2013

Современный способ - с классами java.time.

ZonedDateTime

Укажите шаблон форматирования, соответствующий вашей входной строке. Коды похожи на SimpleDateFormat, но не совсем. Обязательно прочитайте документацию класса для DateTimeFormatter< /а>. Обратите внимание, что мы указываем Locale, чтобы определить, какой человеческий язык использовать для названия дня недели и названия месяца.

String input = "Wed Jul 08 17:08:48 GMT 2009";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "EEE MMM dd HH:mm:ss z uuuu" , Locale.ENGLISH );
ZonedDateTime zdt = ZonedDateTime.parse ( input , f );

zdt.toString(): 2009-07-08T17:08:48Z[GMT]

Мы можем настроить это на любой другой часовой пояс.

Укажите правильное название часового пояса в формате continent/region. Никогда не используйте сокращения из 3-4 букв, такие как CDT или EST или IST, так как они не являются настоящими часовыми поясами, не стандартизированы и даже не уникальны (!).

Я предполагаю, что под CDT вы имели в виду часовой пояс, например America/Chicago.

ZoneId z = ZoneId.of( "America/Chicago" );
ZonedDateTime zdtChicago = zdt.withZoneSameInstant( z );

zdtChicago.toString() 2009-07-08T12:08:48-05:00[Америка/Чикаго]

Instant

Вообще лучше всего работать в UTC. Для этого извлеките файл Instant. Класс Instant представляет момент на временная шкала в UTC с разрешением наносекунды (до девяти (9) цифр десятичной дроби).

Этот класс Instant является базовым классом строительных блоков java.time. Вы можете думать о ZonedDateTime как о Instant плюс ZoneId.

Instant instant = zdtChicago.toInstant();

Instant.toString(): 2009-07-08T17:08:48Z


О java.time

Платформа java.time встроен в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, .Calendar и java.text.SimpleDateFormat.

Проект Joda-Time, теперь в режим обслуживания, советует перейти на java.time.

Чтобы узнать больше, см. учебник по Oracle. И поищите множество примеров и пояснений в Stack Overflow. Спецификация: JSR 310.

Где получить классы java.time?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательным полигоном для возможных дополнений к java.time в будущем. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и подробнее.

person Basil Bourque    schedule 12.10.2016