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

Преобразование временной зоны

Мне нужно преобразовать из одного часового пояса в другой часовой пояс в моем проекте.

Я могу конвертировать из моего текущего часового пояса в другой, но не из другого часового пояса в другой.

Например, я в Индии, и я могу конвертировать из Индии в США с помощью Date d=new Date(); и назначать его календарному объекту и устанавливать часовой пояс.

Однако я не могу сделать это из разных часовых поясов в другой часовой пояс. Например, я в Индии, но у меня возникают проблемы с переходом часовых поясов из США в Великобританию.

4b9b3361

Ответ 1

ТЛ; др

ZonedDateTime.now( ZoneId.of( "Pacific/Auckland" ))              // Current moment in a particular time zone.
             .withZoneSameInstant( ZoneId.of( "Asia/Kolkata" )  // Same moment adjusted into another time zone. 

подробности

Класс java.util.Date не имеет назначенного часового пояса но его реализация toString смущает применение текущего часового пояса JVM по умолчанию.

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

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

java.time

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

Большая часть функциональности java.time была перенесена в Java 6 & 7 в проекте ThreeTen-Backport. Далее адаптирован под Android в проекте ThreeTenABP.

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

Joda времени

Ниже приведен пример кода в Joda-Time 2.3. Поищите в StackOveflow еще много примеров и много обсуждений.

DateTimeZone timeZoneLondon = DateTimeZone.forID( "Europe/London" );
DateTimeZone timeZoneKolkata = DateTimeZone.forID( "Asia/Kolkata" );
DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );

DateTime nowLondon = DateTime.now( timeZoneLondon ); // Assign a time zone rather than rely on implicit default time zone.
DateTime nowKolkata = nowLondon.withZone( timeZoneKolkata );
DateTime nowNewYork = nowLondon.withZone( timeZoneNewYork );
DateTime nowUtc = nowLondon.withZone( DateTimeZone.UTC );  // Built-in constant for UTC.

У нас есть четыре представления одного и того же момента на временной шкале Вселенной.


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

Ответ 2

Некоторые примеры

Преобразование времени между часовым поясом

Преобразование времени между часовыми поясами

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class TimeZoneExample {
    public static void main(String[] args) {
        // Create a calendar object and set it time based on the local
        // time zone
        Calendar localTime = Calendar.getInstance();
        localTime.set(Calendar.HOUR, 17);
        localTime.set(Calendar.MINUTE, 15);
        localTime.set(Calendar.SECOND, 20);

        int hour = localTime.get(Calendar.HOUR);
        int minute = localTime.get(Calendar.MINUTE);
        int second = localTime.get(Calendar.SECOND);


        // Print the local time
        System.out.printf("Local time  : %02d:%02d:%02d\n", hour, minute, second);


        // Create a calendar object for representing a Germany time zone. Then we
        // wet the time of the calendar with the value of the local time

        Calendar germanyTime = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin"));
        germanyTime.setTimeInMillis(localTime.getTimeInMillis());
        hour = germanyTime.get(Calendar.HOUR);
        minute = germanyTime.get(Calendar.MINUTE);
        second = germanyTime.get(Calendar.SECOND);


        // Print the local time in Germany time zone
        System.out.printf("Germany time: %02d:%02d:%02d\n", hour, minute, second);
    }
}

Ответ 3

    Date date = new Date();
    String formatPattern = ....;
    SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);

    TimeZone T1;
    TimeZone T2;

    // set the Calendar of sdf to timezone T1
    sdf.setTimeZone(T1);
    System.out.println(sdf.format(date));

    // set the Calendar of sdf to timezone T2
    sdf.setTimeZone(T2);
    System.out.println(sdf.format(date));

    // Use the 'calOfT2' instance-methods to get specific info
    // about the time-of-day for date 'date' in timezone T2.
    Calendar calOfT2 = sdf.getCalendar();

Ответ 4

Часового пояса "по умолчанию" можно полностью избежать, просто установив часовой пояс для объекта Calendar. Тем не менее, я лично предложил бы использовать Joda Time как далеко превосходящий API для операций даты и времени в Java. Среди прочего, изменение часового пояса в Джоде очень просто.

Непонятно, как выглядит ваш текущий код и почему вы можете конвертировать только через часовой пояс по умолчанию, но в Joda Time вы просто указываете часовой пояс явно при создании (скажем) a DateTime, а затем используйте withZone(DateTimeZone zone).

Если бы вы могли рассказать нам больше о том, как вы получаете входные данные, мы могли бы привести более полный пример.

Ответ 5

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

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));

Ответ 6

Если вы не хотите использовать Joda, это детерминированный способ использования встроенных библиотек.

Прежде всего, я рекомендую вам настроить JVM по умолчанию на часовой пояс. Это касается проблем, которые могут возникнуть при перемещении вашей JVM с одного компьютера на другой, который настроен на разные временные интервалы, но ваши исходные данные всегда являются определенным часовым поясом. Например, допустим, что ваши данные всегда являются часовым поясом PDT/PST, но вы запускаете поле, установленное в часовой пояс UTC.

Следующий фрагмент кода устанавливает часовой пояс по умолчанию в моей JVM:

 //You can either pass the JVM a parameter that 
 //enforces a TZ: java -Duser.timezone=UTC or you can do it
 //programatically like this
 TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
 TimeZone.setDefault(tz);

Теперь давайте укажем, что дата вашего источника поступает как PDT/PST, но вам нужно преобразовать ее в UTC. Это следующие шаги:

    DateFormat dateFormatUtc = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    dateFormatUtc.setTimeZone(TimeZone.getTimeZone("UTC"));

    String dateStrInPDT = "2016-05-19 10:00:00";
    Date dateInPDT = dateFormat.parse(dateStrInPDT);


    String dateInUtc = dateFormatUtc.format(dateInPDT);

    System.out.println("Date In UTC is " + dateInUtc);

Вывод будет:

Date In UTC is 2016-05-19 17:00:00

Ответ 7

Вы можете сделать что-то подобное, чтобы получить текущее время в другом часовом поясе.

Calendar japanCal = new GregorianCalendar(TimeZone.getTimeZone("Japan"));
japanCal.setTimeInMillis(local.getTimeInMillis());

Ответ 8

Зависит от того, что вы действительно подразумеваете под "преобразованием".

Это МОЖЕТ быть так же просто, как установить часовой пояс в FORMATTER, а не отключать календарь вообще.

Calendar cal = Calendar.getInstance();

TimeZone tzUTC = TimeZone.getTimeZone( "UTC" );
TimeZone tzPST = TimeZone.getTimeZone( "PST8PDT" );

DateFormat dtfmt = new SimpleDateFormat( "EEE, yyyy-MM-dd KK:mm a z" );

dtfmt.setTimeZone( tzUTC );
System.out.println( "UTC: " + dtfmt.format( cal.getTime() ));

dtfmt.setTimeZone( tzPST );
System.out.println( "PST: " + dtfmt.format( cal.getTime() ));

Ответ 9

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

public static Date toGreekTimezone (Date date) {
  ZoneId greek = ZoneId.of(EUROPE_ATHENS);
  ZonedDateTime greekDate = ZonedDateTime.ofInstant(date.toInstant(), greek);

  ZoneId def = ZoneId.systemDefault();
  ZonedDateTime defDate = greekDate.withZoneSameLocal(def);

  return Date.from(defDate.toInstant());
}

Ответ 10

Вы можете использовать метод java.time.ZoneDateTime#ofInstant():

import java.time.*;

public class TimeZonesConversion {
    static ZonedDateTime convert(ZonedDateTime time, ZoneId newTimeZone) {
        return ZonedDateTime.ofInstant(
                time.toInstant(),
                newTimeZone);
    };

    public static void main(String... args) {
        ZonedDateTime mstTime = ZonedDateTime.of(LocalDateTime.now(), ZoneId.of("-07")); 
        ZonedDateTime localTime = convert(mstTime, Clock.systemDefaultZone().getZone());
        System.out.println("MST(" + mstTime + ") = " + localTime);
    }
}

Ответ 11

public static void convertTimeZone(Date date, TimeZone fromTimeZone, TimeZone toTimeZone) {
    long milliseconds = date.getTime();
    milliseconds += (fromTimeZone.getRawOffset() * -1);
    if (fromTimeZone.inDaylightTime(date)) {
        milliseconds += (fromTimeZone.getDSTSavings() * -1);
    }
    milliseconds += toTimeZone.getRawOffset();
    if (toTimeZone.inDaylightTime(date)) {
        milliseconds += toTimeZone.getDSTSavings();
    }
    date.setTime(milliseconds);
}