2013-04-03 5 views
6

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

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

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

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

+0

FYI, неприятные старые классы времени, такие как 'TimeZone', [' java.util.Date'] (https://docs.oracle.com/javase/9/docs/api/java/util/ Date.html), ['java.util.Calendar'] (https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html) и' java.text.SimpleDateFormat' теперь [наследие] (https://en.wikipedia.org/wiki/Legacy_system), вытесненное [java.time] (https://docs.oracle.com/javase/9/docs/api/java/ time/package-summary.html), встроенные в Java 8 и Java 9. См. [* Tutorial * by Oracle] (https://docs.oracle.com/javase/tutorial/datetime/TOC.html). –

ответ

14

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

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

+0

Я хочу смещение * включая * DST. –

+0

Извините, что публиковать сообщения в такой старой теме, но у меня есть путаница. Если я использую TimeZone.getOffset (long date), он предполагает, что параметр даты находится в местном или UTC? В частности, если вы называете это с датой, которая составляет несколько часов до того, как будет установлен переход на летнее время в Нью-Йорке, но через несколько часов в UTC будет включен переключатель или нет? –

+0

длинная дата - миллисекунды с 1970-01-01 UTC. –

7

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

TimeZone.getTimeZone("America/New_York").getOffset(Calendar.getInstance().getTimeInMillis()) 
7

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

TimeZone tz1 = TimeZone.getTimeZone("GMT"); 
    TimeZone tz2 = TimeZone.getTimeZone("America/New_York"); 
    long timeDifference = tz1.getRawOffset() - tz2.getRawOffset() + tz1.getDSTSavings() - tz2.getDSTSavings(); 
2
public String timeZone(Date date) { 
    TimeZone timeZone = TimeZone.getTimeZone("America/New_York"); 
    long millis = timeZone.getRawOffset() + (timeZone.inDaylightTime(date) ? timeZone.getDSTSavings() : 0); 

    return String.format("%s%s:%s", 
      millis < 0 ? "-" : "+", 
      String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toHours(millis))), 
      String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)))) 
    ); 
} 
0

Tl; др

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 класса.

Указать proper time zone name в формате continent/region, такие как America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте аббревиатуру 3-4 буквы, такую ​​как EST или IST, так как они не настоящие часовые пояса, не стандартизированные, и даже не уникальные (!).

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

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

ZoneRules rules = z.getRules() ; 

Задайте правила, если переход на летнее время (DST) действует в определенный момент. Укажите момент как Instant. Класс Instant представляет собой момент на временной шкале в UTC с разрешением nanoseconds (до девяти (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 каркас встроен в Java 8 и более поздних версий. Эти классы вытесняют неприятные старые legacy классы времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

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

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

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

Где получить классы java.time?

  • Java SE 8, Java SE 9, а затем
    • Встроенный.
    • Часть стандартного Java API с объединенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time будет обратно портирован на Java 6 & 7 в ThreeTen-Backport.
  • Android
    • Более поздние версии Android реализаций пачке классов java.time.
    • Для более ранних Android, проект ThreeTenABP адаптируется ThreeTen-Backport (упомянутый выше). См. How to use ThreeTenABP….

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

Смежные вопросы