Конвертировать дату в другой часовой пояс [дубликат]

20

Я пытаюсь получить простое преобразование из одного часового пояса в другое, используя 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 час ... Вся проблема кажется тривиальной, но я не могу найти простой ответ на этот вопрос. Заранее благодарим за помощь.

    
задан Bober02 02.11.2012 в 16:10
источник
  • Хотели бы вы использовать время Джоды? Это мое предпочтение. –  Lion 02.11.2012 в 16:13
  • Проверьте этот ответ. Это может пригодиться. –  Gamb 02.11.2012 в 16:19
  • Я нашел еще одну вещь в Интернете, которая, вероятно, является самым чистым решением, использовать формат даты для анализа строки даты и возврата даты в соответствующий часовой пояс –  Bober02 02.11.2012 в 16:26
  • См. mkyong.com/java/java-convert-date-and-time-between-timezone –  GKislin 20.07.2016 в 12:32

3 ответа

34

Когда вы печатаете дату с использованием 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()))
    
ответ дан Yogendra Singh 02.11.2012 в 16:12
  • Вы уверены, что это местный часовой пояс, а не секунды EPOCH (независимый от часового пояса)? docs.oracle.com/javase/7/docs/api/java/util/... –  akaIDIOT 02.11.2012 в 16:14
  • @akaIDIOT внутреннее представление с эпохи, когда дата печатается, используется местный часовой пояс, функция / ошибка java.util.Date. –  dan 02.11.2012 в 16:18
  • @ Bober02: Вы нашли что-то лучше? Если да, делитесь. –  Yogendra Singh 02.11.2012 в 16:34
  • Очевидно, что formatter.format (instance2.getTime ()) изменяет timeZone, но когда мы преобразуем этот объект даты даты в дату, он снова берет локальный часовой пояс. Есть ли решение для этого? –  Parkash Kumar 21.06.2013 в 12:58
  • @ParkashKumar: Дата независима от часового пояса, поэтому у вас есть два метода обхода. 1. Отрегулируйте смещение для обработки локальной даты с зависимым от часового пояса значением. 2. Используйте объекты, зависящие от временной зоны, с правильной обработкой. –  Yogendra Singh 21.06.2013 в 16:11
11

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

Избегайте java.util.Date & amp; .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.

    
ответ дан Basil Bourque 15.07.2014 в 09:19
2

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

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));
    
ответ дан Srijani Ghosh 15.07.2014 в 06:35