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