2014-11-12 3 views
6

Я использую новую реализацию Java, которая задает вопрос о выходе UTC в CET результат преобразования времени.java.time: Является ли часовой пояс CET летним временем?

ZonedDateTime utcTime = ZonedDateTime.of(2014, 7, 1, 8, 0, 0, 0, ZoneId.of("UTC")); 
ZonedDateTime cetTime = ZonedDateTime.ofInstant(utcTime.toInstant(), ZoneId.of("CET")); 
System.out.println("Summer-UTC-Time: " + utcTime); 
System.out.println("Summer-CET-Time: " + cetTime); 

System.out.println(); 

utcTime = ZonedDateTime.of(2014, 1, 1, 8, 0, 0, 0, ZoneId.of("UTC")); 
cetTime = ZonedDateTime.ofInstant(utcTime.toInstant(), ZoneId.of("CET")); 
System.out.println("Winter-UTC-Time: " + utcTime); 
System.out.println("Winter-CET-Time: " + cetTime); 

Я ожидал, что время CET всегда будет +1 времени UTC, но вместо этого я получил:

Summer-UTC-Time: 2014-07-01T08:00Z[UTC] 
Summer-CET-Time: 2014-07-01T10:00+02:00[CET] -> +2 **Unexpected** 

Winter-UTC-Time: 2014-01-01T08:00Z[UTC] 
Winter-CET-Time: 2014-01-01T09:00+01:00[CET] -> +1 Expected 

Таким образом, очевидно мне приходится иметь дело с переходом на летнее время, которое я не ожидал, что когда используя CET. Действительно ли java.time CET в действительности CEST? И если да, в какой зоне я должен использовать, если мне нужна CET?

+0

'CET' не идентичен« UTC + 1 », по крайней мере, как это определяет база данных часовых поясов IANA. И именно это использует Java, POSIX и несколько поставщиков баз данных. – Holger

+0

@Holger Ваш комментарий «CET не идентичен UTC + 1», кажется, самый правильный ответ, хотя ссылка [wiki] (http://en.wikipedia.org/wiki/Central_European_Time) содержит фиксированное UTC-смещение +1 (+2 будет CEST в регионах с DST). Я быстро посмотрел на IANA, но это не помогло мне понять их определение. Тем не менее, если вы добавите свой комментарий в качестве ответа (возможно, предоставив дополнительную справочную информацию), я бы принял его. – FrVaBe

ответ

10

IANA definition of CET является то, что он следует правилам часовой пояс Центральной Европы, который включает в себя как зимнее, так и летнее время. Правила можно увидеть here, который показывает, что «CET» основан на "C-Eur", который включает летнее время.

В java.time вы также можете увидеть полный набор правил:

ZoneId zone = ZoneId.of("CET"); 
System.out.println(zone); 
System.out.println(zone.getRules()); 
for (ZoneOffsetTransition trans : zone.getRules().getTransitions()) { 
    System.out.println(trans); 
} 
for (ZoneOffsetTransitionRule rule : zone.getRules().getTransitionRules()) { 
    System.out.println(rule); 
} 

, который печатает:

CET 
ZoneRules[currentStandardOffset=+01:00] 
Transition[Gap at 1916-04-30T23:00+01:00 to +02:00] 
Transition[Overlap at 1916-10-01T01:00+02:00 to +01:00] 
Transition[Gap at 1917-04-16T02:00+01:00 to +02:00] 
Transition[Overlap at 1917-09-17T03:00+02:00 to +01:00] 
Transition[Gap at 1918-04-15T02:00+01:00 to +02:00] 
Transition[Overlap at 1918-09-16T03:00+02:00 to +01:00] 
Transition[Gap at 1940-04-01T02:00+01:00 to +02:00] 
Transition[Overlap at 1942-11-02T03:00+02:00 to +01:00] 
Transition[Gap at 1943-03-29T02:00+01:00 to +02:00] 
Transition[Overlap at 1943-10-04T03:00+02:00 to +01:00] 
Transition[Gap at 1944-04-03T02:00+01:00 to +02:00] 
Transition[Overlap at 1944-10-02T03:00+02:00 to +01:00] 
Transition[Gap at 1945-04-02T02:00+01:00 to +02:00] 
Transition[Overlap at 1945-09-16T03:00+02:00 to +01:00] 
Transition[Gap at 1977-04-03T02:00+01:00 to +02:00] 
Transition[Overlap at 1977-09-25T03:00+02:00 to +01:00] 
Transition[Gap at 1978-04-02T02:00+01:00 to +02:00] 
Transition[Overlap at 1978-10-01T03:00+02:00 to +01:00] 
Transition[Gap at 1979-04-01T02:00+01:00 to +02:00] 
Transition[Overlap at 1979-09-30T03:00+02:00 to +01:00] 
Transition[Gap at 1980-04-06T02:00+01:00 to +02:00] 
Transition[Overlap at 1980-09-28T03:00+02:00 to +01:00] 
Transition[Gap at 1981-03-29T02:00+01:00 to +02:00] 
Transition[Overlap at 1981-09-27T03:00+02:00 to +01:00] 
Transition[Gap at 1982-03-28T02:00+01:00 to +02:00] 
Transition[Overlap at 1982-09-26T03:00+02:00 to +01:00] 
Transition[Gap at 1983-03-27T02:00+01:00 to +02:00] 
Transition[Overlap at 1983-09-25T03:00+02:00 to +01:00] 
Transition[Gap at 1984-03-25T02:00+01:00 to +02:00] 
Transition[Overlap at 1984-09-30T03:00+02:00 to +01:00] 
Transition[Gap at 1985-03-31T02:00+01:00 to +02:00] 
Transition[Overlap at 1985-09-29T03:00+02:00 to +01:00] 
Transition[Gap at 1986-03-30T02:00+01:00 to +02:00] 
Transition[Overlap at 1986-09-28T03:00+02:00 to +01:00] 
Transition[Gap at 1987-03-29T02:00+01:00 to +02:00] 
Transition[Overlap at 1987-09-27T03:00+02:00 to +01:00] 
Transition[Gap at 1988-03-27T02:00+01:00 to +02:00] 
Transition[Overlap at 1988-09-25T03:00+02:00 to +01:00] 
Transition[Gap at 1989-03-26T02:00+01:00 to +02:00] 
Transition[Overlap at 1989-09-24T03:00+02:00 to +01:00] 
Transition[Gap at 1990-03-25T02:00+01:00 to +02:00] 
Transition[Overlap at 1990-09-30T03:00+02:00 to +01:00] 
Transition[Gap at 1991-03-31T02:00+01:00 to +02:00] 
Transition[Overlap at 1991-09-29T03:00+02:00 to +01:00] 
Transition[Gap at 1992-03-29T02:00+01:00 to +02:00] 
Transition[Overlap at 1992-09-27T03:00+02:00 to +01:00] 
Transition[Gap at 1993-03-28T02:00+01:00 to +02:00] 
Transition[Overlap at 1993-09-26T03:00+02:00 to +01:00] 
Transition[Gap at 1994-03-27T02:00+01:00 to +02:00] 
Transition[Overlap at 1994-09-25T03:00+02:00 to +01:00] 
Transition[Gap at 1995-03-26T02:00+01:00 to +02:00] 
Transition[Overlap at 1995-09-24T03:00+02:00 to +01:00] 
Transition[Gap at 1996-03-31T02:00+01:00 to +02:00] 
Transition[Overlap at 1996-10-27T03:00+02:00 to +01:00] 
Transition[Gap at 1997-03-30T02:00+01:00 to +02:00] 
Transition[Overlap at 1997-10-26T03:00+02:00 to +01:00] 
TransitionRule[Gap +01:00 to +02:00, SUNDAY on or after MARCH 25 at 02:00 STANDARD, standard offset +01:00] 
TransitionRule[Overlap +02:00 to +01:00, SUNDAY on or after OCTOBER 25 at 02:00 STANDARD, standard offset +01:00] 

Ключевым моментом здесь является понимание того, что идентификатор часового пояса и "short name" этого Идентификатор - это два разных элемента. Идентификатор всегда фиксируется как «CET», но имя изменяется между «CET» и «CEST».

+0

Все еще запутываю для меня, что это как-то отличается от обычного объяснения CET, которое можно найти за пределами IANA (например, wikipedia), но, безусловно, лучший и правильный ответ. Благодарю. – FrVaBe

1

Потому что вы знаете смещение и не хотите использовать DTS, почему бы не использовать метод ZoneOffset.ofHours(1) вместо ZoneId.of("CET")?

Также вы можете позвонить normalized() на любой экземпляр ZoneId, чтобы сделать его фиксированным смещением, но звучит менее надежным, чем использование смещения с самого начала.

От ZoneId javadoc:

ZoneId используется для определения правил, используемых для преобразования между Instant и в LocalDateTime. Есть два различных типа ID:

  • Фиксированные смещения - полностью решённые смещение от UTC/Гринвич, который использует то же смещение для всех локальных дата-время
  • Географические регионы - район, где конкретный набор правила для поиска смещения от UTC/Greenwich apply

Большинство фиксированных смещений представлены ZoneOffset. Вызов normalized() на любом ZoneId гарантирует, что фиксированный идентификатор смещения будет представлен как ZoneOffset.

Если вы не используете фиксированные смещения, то вы используете географические регионы, что означает, что он зависит от региона, если наблюдается DTS или нет. То же самое происходит с PST. Вы увидите, что он наблюдает за DTS, хотя летнее время называется PDT. Да, это запутывает, но именно так работают большинство инструментов. Прочтите полный текст ZoneId javadoc для более подробного объяснения (раздел Time-zone IDs).

+0

Мне нужно прочитать значение даты из базы данных, которую я считаю в CET. Я думал, используя TimeZone, и соответствующие правила будут обрабатывать смещения и летнее время (если применимо) для меня. – FrVaBe

+0

@FrVaBe, он должен справиться с этим. Прочтите http://www.timeanddate.com/time/zones/cet. Вы увидите, что эта зона охватывает регионы, которые выполняют DTS наблюдателя. Существуют регионы с одинаковым часовым поясом, но без DTS, которые написаны как +1. Считаете ли вы, что система, хранящая значения в БД, использует CET для областей, которые на самом деле +1? Кстати, это одна из причин всегда хранить UTC в БД. Другое дело, что местное время с DTS не может быть однозначно преобразовано в UTC. – akostadinov

+0

Я просто подумал - как указано в предоставленной вами ссылке - CET всегда UTC + 1 - в противном случае это будет CEST. В этом случае CET будет так же хорош, как и UTC. Преобразование между ними было бы простым, но теперь я наблюдаю, что DST имеет значение в CET, и мне интересно, почему. Мой простой вопрос может быть: Почему CET не всегда UTC + 1 при использовании java.time? – FrVaBe

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