Java: расчет разницы часовых поясов

Как мне получить разницу во времени от GMT для определенной даты и часового пояса в Java?

Определить, находится ли конкретный часовой пояс в DST, довольно просто:

boolean isIsraelInDST = TimeZone.getTimeZone("Israel").inDaylightTime(new Date());

Как узнать реальную разницу во времени?


person Adam Matan    schedule 03.04.2013    source источник
comment
К вашему сведению, неприятные старые классы даты и времени, такие как TimeZone, java.util.Date, java.util.Calendar , и java.text.SimpleDateFormat теперь являются устаревшими, замененными java.time классы, встроенные в Java 8 и Java 9. См. Учебное пособие от Oracle.   -  person Basil Bourque    schedule 26.02.2018


Ответы (4)


Use TimeZone.getRawOffset (): Возвращает количество времени в миллисекундах, которое нужно добавить к UTC, чтобы получить стандартное время в этом часовом поясе. Поскольку на это значение не влияет переход на летнее время, оно называется необработанным смещением.

Если вы хотите, чтобы смещение включало летнее время, используйте TimeZone.getOffset (длинная дата). Вы должны указать конкретную дату для метода, например now - System.currentTimeMillis ()

person Evgeniy Dorofeev    schedule 03.04.2013
comment
Я хочу, чтобы смещение включая летнее время. - person Adam Matan; 03.04.2013
comment
Извините, что отправил в такую ​​старую ветку, но у меня путаница. Если я использую TimeZone.getOffset (длинную дату), предполагает ли он, что параметр даты находится в местном времени или UTC? В частности, если вы вызываете его с датой, которая находится за несколько часов до перехода на летнее время в Нью-Йорке, но через несколько часов после UTC, будет ли он включать переключатель или нет? - person Steve Bauer; 08.02.2018
comment
длинная дата - это миллисекунды с 1970-01-01 UTC. - person Evgeniy Dorofeev; 09.02.2018
comment
Обновление: класс TimeZone был вытеснен много лет назад с принятием JSR 310. Вместо этого используйте ZoneId и ZoneRules. - person Basil Bourque; 15.03.2019

Я предлагаю добавить смещение летнего / зимнего времени в getRawOffset:

    TimeZone tz1 = TimeZone.getTimeZone("GMT");
    TimeZone tz2 = TimeZone.getTimeZone("America/New_York");
    long timeDifference = tz1.getRawOffset() - tz2.getRawOffset() + tz1.getDSTSavings() - tz2.getDSTSavings();
person Andy Malakov    schedule 06.06.2014
comment
Разве вам не нужно проверять, действует ли летнее время, прежде чем настраивать с помощью tz2.inDaylightTime (new Date ()); - person Martin; 03.04.2018

tl;dr

ZoneId.of( "Pacific/Auckland" )   // Specify a time zone.
    .getRules()                   // Get the object representing the rules for all the past, present, and future changes in offset used by the people in the region of that zone.
    .getOffset( Instant.now() )   // Get a `ZoneOffset` object representing the number of hours, minutes, and seconds displaced from UTC. Here we ask for the offset in effect right now.
    .toString()                   // Generate a String in standard ISO 8601 format.

+13:00

На первый момент определенной даты.

ZoneId.of( "Pacific/Auckland" )
    .getRules()
    .getOffset( 
        LocalDate.of( 2018 , Month.AUGUST , 23 )          // Specify a certain date. Has no concept of time zone or offset.
        .atStartOfDay( ZoneId.of( "Pacific/Auckland" ) )  // Determine the first moment of the day on that date in that region. Not always `00:00:00` because of anomalies such as Daylight Saving Time.
        .toInstant()                                      // Adjust to UTC by extracting an `Instant`. 
    ) 
    .toString()

+12:00

Избегайте устаревших классов даты и времени

Остальные ответы устарели, так как класс TimeZone теперь унаследован. Этот и другие неудобные старые классы времени и даты заменяются классами времени java.time.

java.time

Теперь мы используем ZoneId, ZoneOffset и ZoneRules. вместо унаследованного класса TimeZone.

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

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;  

Получите правила для этой зоны.

ZoneRules rules = z.getRules() ;

Спросите у правил, действует ли в определенный момент летнее время (DST). Укажите момент как Instant. Класс Instant представляет момент на временной шкале. в UTC с разрешением наносекунды (до девяти (9) цифр десятичной дроби).

Instant instant = Instant.now() ;  // Capture current moment in UTC.
boolean isDst = rules.isDaylightSavings( instant ) ;

Как узнать реальную разницу во времени?

Не уверен, что вы имеете в виду, но я предполагаю, что вы запрашиваете offset-from-UTC в эффект в этот момент для той зоны. Смещение - это смещение в часах, минутах и ​​секундах от UTC. Мы представляем смещение с помощью класса ZoneOffset. Часовой пояс - это история прошлых, настоящих и будущих изменений в смещении, используемом людьми определенного региона. Мы представляем часовой пояс с помощью класса ZoneId.

Поскольку смещение может меняться со временем для региона, мы должны пропустить момент при запросе смещения.

ZoneOffset offset = rules.getOffset( instant ) ;

Создайте строку, представляющую это смещение в стандартном формате ISO 8601.

String output output = offset.toString() ;

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

int offsetInSeconds = offset.getTotalSeconds() ;

О java.time

java.time framework встроена в Java 8 и новее. Эти классы заменяют неудобные старые устаревшие классы даты и времени, такие как _ 24_, _ 25_, & _ 26_.

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

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

Использование драйвера JDBC, совместимого с JDBC 4.2 или новее, вы можете обмениваться объектами java.time непосредственно с вашей базой данных. Не нужны ни строки, ни классы java.sql. *.

Где взять классы java.time?

  • Java SE 8, Java SE 9, and later
    • Built-in.
    • Часть стандартного Java API со встроенной реализацией.
    • В Java 9 добавлены некоторые незначительные функции и исправления.
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • Для более ранней версии Android проект ThreeTenABP адаптируется к < em> ThreeTen-Backport (упомянутый выше). См. Как использовать ThreeTenABP….

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

person Basil Bourque    schedule 26.02.2018

Я вижу, что это старый поток, но добавив его, поскольку недавно у меня было аналогичное требование - это дает фактическую разницу в миллисекундах на основе ТЕКУЩЕГО времени (миллисекунд от эпохи).

    TimeZone.getTimeZone("America/New_York").getOffset(Calendar.getInstance().getTimeInMillis())
person Vinay Rao    schedule 05.05.2014