Подтвердить что ты не робот

Преобразование даты в другой часовой пояс

Я пытаюсь получить простое преобразование из одного часового пояса в другое, используя Java Date и Calendar. Я пытаюсь запустить следующий код

    Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("Europe/London"));
    Date date = instance.getTime();
    System.out.println(date);

    GregorianCalendar instance2 = new GregorianCalendar(TimeZone.getTimeZone("Europe/Athens"));
    instance2.setTime(instance.getTime());
    System.out.println(instance2.getTime());

но все же возвращает ту же дату, а не +1 час... Вся проблема кажется тривиальной, но я не могу найти простой ответ на этот вопрос. Заранее благодарим за помощь.

4b9b3361

Ответ 1

Когда вы печатаете дату с помощью System.out.println(date); or System.out.println(instance2.getTime());, Date, возвращаемый instance2.getTime(), является TimeZone independent и всегда печатает дату в локальном часовом поясе.

Вместо этого вы можете использовать DateFormat/SimpleDateFormat:

  DateFormat formatter= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss Z");
  formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
  System.out.println(formatter.format(date));

  formatter.setTimeZone(TimeZone.getTimeZone("Europe/Athens"));
  System.out.println(formatter.format(instance2.getTime()))

Ответ 2

Принятый ответ правильный. Класс java.util.Date не имеет назначенного часового пояса но реализация toString путается, применяя часовой пояс по умолчанию JVM.

Избегайте java.util.Date и .Calendar

Это одна из многих причин, чтобы избежать печально известных проблемных классов java.util.Date,.Calendar и SimpleDateFormat в комплекте с Java. Избежать их. Вместо этого используйте либо:

Joda времени

Следующий пример кода в Joda-Time 2.3. Поиск StackOveflow для многих других примеров и много обсуждений.

DateTimeZone timeZoneLondon = DateTimeZone.forID( "Europe/London" );
DateTimeZone timeZoneAthens = DateTimeZone.forID( "Europe/Athens" );

DateTime nowLondon = DateTime.now( timeZoneLondon );
DateTime nowAthens = nowLondon.withZone( timeZoneAthens );
DateTime nowUtc = nowLondon.withZone( DateTimeZone.UTC );

java.time

Java 8 и более поздние версии имеют новый пакет java.time. Этот пакет был вдохновлен Joda-Time. Хотя они разделяют некоторые сходства и имена классов, они различны; у каждого есть свои недостатки. Одна заметная разница заключается в том, что java.time избегает конструкторов, вместо этого использует статические методы создания экземпляров.

В случае этого Вопроса они работают одинаково. Укажите часовой пояс и вызовите метод now, чтобы получить текущий момент, затем создайте новый экземпляр, основанный на старом неизменяемом экземпляре, для настройки часовой пояс.

Обратите внимание на два разных класса часовых поясов. Один из них - это именованный часовой пояс, включающий все правила для летнего времени и другие подобные аномалии плюс смещение от UTC, а другое - только смещение.

ZoneId zoneMontréal = ZoneId.of("America/Montreal"); 
ZonedDateTime nowMontréal = ZonedDateTime.now ( zoneMontréal );

ZoneId zoneTokyo = ZoneId.of("Asia/Tokyo"); 
ZonedDateTime nowTokyo = nowMontréal.withZoneSameInstant( zoneTokyo );

ZonedDateTime nowUtc = nowMontréal.withZoneSameInstant( ZoneOffset.UTC );

На самом деле класс java.util.Date имеет часовой пояс, похороненный в его исходный код. Но класс игнорирует этот часовой пояс для большинства практических целей. Таким образом, в качестве сокращения, его часто говорят, что j.u.Date не имеет назначенного часового пояса. Смешение? Да. Избегайте беспорядка, который является j.u.Date, и отправляйтесь с Joda-Time и/или java.time.

Ответ 3

Вы можете использовать следующий фрагмент кода

String dateString = "14 Jul 2014 00:11:04 CEST";
date = formatter.parse(dateString);
System.out.println(formatter.format(date));

// Set the formatter to use a different timezone - Indochina Time
formatter.setTimeZone(TimeZone.getTimeZone("Asia/Bangkok"));
System.out.println("ICT time : "+formatter.format(date));