tl; д-р
OffsetDateTime.now().getOffset()
Але ви, швидше за все, повинні використовувати часовий пояс, а не просто зсув від UTC.
ZoneId.systemDefault()
Зсув проти часового поясу
Офсетний через UTC є лише кількістю годин, хвилин і секунд - більше нічого. Наприклад, -08:00
означає вісім годин позаду UTC, а +05:45
означає п’ять годин сорок п’ять хвилин перед UTC .
Часовий пояс є історія минулого, теперішнього і майбутніх змін в зміщення , який використовується людьми конкретного регіону. Такі аномалії, як перехід на літній та зимовий час (DST), що спричиняють зміщення зсуву протягом певних періодів часу, відстежуються з плином часу, як у минулому, так і в майбутньому, коли політики оголосили про заплановані зміни.
Тож краще використовувати зону, коли вона відома.
Зміщення для будь-якого регіону змінюється з часом. Наприклад, літній час у Сполучених Штатах зміщує зміщення на годину приблизно на півроку, а потім відновлює цю годину до зсуву протягом другої половини року. Вся мета часового поясу полягає в тому, щоб задокументувати ці зрушення у зсуві.
Тому насправді немає сенсу просити компенсацію без дати та часу . Наприклад America/Los_Angeles
, наприклад, в частині цього року зсув є, -08:00
але в іншій частині року - -07:00
під час переходу на літній час.
OffsetDateTime
Тож давайте визначимо момент як а OffsetDateTime
, а потім витягніть ZoneOffset
.
OffsetDateTime odt = OffsetDateTime.now ();
ZoneOffset zoneOffset = odt.getOffset ();
odt.toString (): 2017-01-02T15: 19: 47.162-08: 00
zoneOffset.toString (): -08: 00
Цей now
метод фактично неявно застосовує поточний часовий пояс JVM за замовчуванням. Я пропоную вам завжди чітко це вказувати, вказуючи бажаний / очікуваний часовий пояс. Навіть якщо вам потрібна поточна зона за замовчуванням, прямо скажіть це, щоб чітко пояснити свої наміри. Усуньте двозначність щодо того, чи планували ви за замовчуванням чи не враховували часовий пояс, як це часто трапляється у програмістів. Телефонуйте ZoneId.systemDefault
.
OffsetDateTime odt = OffsetDateTime.now ( ZoneId.systemDefault () );
ZoneOffset zoneOffset = odt.getOffset ();
ZoneId.systemDefault (). ToString (): America / Los_Angeles
odt: 2017-01-02T15: 19: 47.162-08: 00
zoneOffsetOfOdt: -08: 00
Застереження щодо залежності від зони за замовчуванням. Це значення за замовчуванням може бути змінено в будь-який момент будь-яким кодом у будь-якому потоці в JVM. Якщо це важливо, запитайте у користувача передбачуваний часовий пояс.
Ви можете попросити зсув за його проміжок часу як загальну кількість секунд.
int offsetSeconds = zoneOffset.getTotalSeconds ();
offsetSeconds: -28800
ZonedDateTime
Інший приклад: можливо, ви хочете знати, яким буде компенсація на Різдво цього року в Квебеку. Вкажіть часовий пояс America/Montreal
, отримайте a ZonedDateTime
, попросіть його зміщення як ZoneOffset
об’єкт.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate ld = LocalDate.of( 2017 , 12 , 25 );
ZonedDateTime zdtXmas = ld.atStartOfDay( z );
ZoneOffset zoneOffsetXmas = zdtXmas.getOffset();
zdtXmas.toString (): 2017-12-25T00: 00-05: 00 [Америка / Монреаль]
zoneOffsetXmas.toString (): -05: 00
zoneOffsetXmas.getTotalSeconds (): -18000
ZoneId
Як запропоновано в коментарі yanys, ви можете допитати a ZoneId
для конкретного ZoneOffset
, передавши момент як Instant
. Instant
Клас являє собою момент на часовій шкалі в форматі UTC з дозволом наносекунд (до дев'яти (9) цифр десяткового дробу).
Це просто ще один шлях до того ж пункту призначення. Так само, як OffsetDateTime
і ZonedDateTime
обговорювалося вище, ми вказуємо (а) часовий пояс і (б) момент.
Instant instant = zdtXmas.toInstant();
ZoneOffset zo = z.getRules().getOffset( instant );
Для ZoneId: Америка / Монреаль миттєво: 2017-12-25T05: 00: 00Z ZoneOffset: -05: 00
Перегляньте код усіх цих прикладів у прямому ефірі на IdeOne.com .
ZoneOffset.systemDefault
- Помилка чи особливість?
ZoneOffset
Клас, підклас ZoneId
, документований як успадкувати systemDefault
метод. Однак це насправді не працює.
ZoneOffset zoneOffset = ZoneOffset.systemDefault() ;
помилка: несумісні типи: ZoneId не можна перетворити на ZoneOffset
Не впевнений, чи є ця помилка компіляції помилкою чи функцією. Як обговорювалося вище, мені здається, не має сенсу коли-небудь просити компенсацію за замовчуванням з датою-часом, тому, можливо, це ZoneOffset.systemDefault
дійсно повинно провалитися. Але в документації повинно бути так, з поясненнями.
Я намагався подати повідомлення про помилку, оскільки документ не міг вирішити цю проблему, але відмовився, не маючи можливості визначити, де і як подати такий звіт про помилку.
Сонячний час проти політичного часу
Трохи більше про зміщення та часові пояси ...
Сонячний час використовувався з попередньої історії, відстежуючи кожен день, відзначаючи, коли сонце прямо над головою. Засуньте палицю в землю і спостерігайте за її тінню. Коли тінь найкоротша, коли тінь починає рости, а не стискатися, ви знаєте, що зараз полудень. Формалізуйте це за допомогою сонячного годинника, щоб відстежувати години.
З сонячним часом, коли ви їдете з міста в місто, рухаючись на захід, полудень приходить трохи пізніше. Рухаючись на схід, полудень приходить трохи раніше. Отже, кожне місто має власний полудень, спільний лише для міст на півночі та півдні на одній довготі.
У сучасну епоху сонячний час був в основному відмовлений. Коли прибували поїзди, телеграфи та телефони, виникала і необхідність тимчасової координації. Отож, точка була вибрана для ближнього сонячного часу полудня, і велика ділянка суші на стільки миль на захід і на схід оголошено всім поділяти однакові 12:00 на годиннику, таку ж кількість годин, зміщених вперед або за лінією Грінвічського первинного меридіана . Так розпочалася традиція, що кожна зупинка поїздів видно демонструє годинник, щоб місто знало стандартний час для свого більшого регіону, а не сонячний час для власного міста. Як правило, у містах на західній околиці цього часового поясу годинник залізничного вокзалу буде читатись 12:00 трохи ранішесонце над головою. Годинники в містах на східному краю області показують 12:00 трохи після того, як сонце над головою.
Політики у всьому світі виявляли схильність до зміни відступу своєї юрисдикції. Причини різні, такі як дипломатія, війна та окупація, а також глупота літнього часу . Причини різні, але їх зміни відбуваються з дивовижною частотою. Часовий пояс - це назва регіону для відстеження історії таких змін. Отже, зсув від UTC є лише кількістю годин-хвилин-секунд вперед чи позаду меридіана. Часовий пояс набагато більше: історія з минулого, теперішнього і майбутніх змін до зсувів конкретного регіону. Хоча сьогодні два сусідні регіони можуть поділяти один і той же зсув від UTC, в минулому чи в майбутньому вони можуть відрізнятися залежно від різних примх чи логіки їх політиків.
Це означає, що сучасне відстеження часу, визначене політиками, мало пов’язане з географією. Наприклад, величезна країна Індія сьогодні має єдиний часовий пояс (зсув від UTC +05: 30). Тож сонячний полудень (сонце прямо над головою) - це години в різних місцях величезного субконтиненту. Політики Індії вирішили це допомогти об'єднати їх різноманітну демократію. В інших прикладах по всьому світу ми бачимо, як регіони використовують свій часовий пояс як символ міжнародних відносин, таких як відмінність від країни-сусіда, що обижається, або вибір тієї ж зони в якості сусіда, оскільки відносини відтають, як нещодавно спостерігалося в Північній Кореї, що змінюється відповідно до Південна Корея. Отже, сьогодні сонячний час є лише одним із кількох міркувань при відстеженні часу.
Про java.time
Java.time каркас вбудований в Java 8 і пізніших версій. Ці класи витісняти неприємні старі застарілі класи дати і часу , такі як java.util.Date
, Calendar
, і SimpleDateFormat
.
Щоб дізнатись більше, див. Підручник Oracle . І шукайте в Stack Overflow багато прикладів та пояснень. Специфікація - JSR 310 .
Проект Joda-Time , який зараз перебуває в режимі обслуговування , радить перейти на класи java.time .
Ви можете обмінювати об'єкти java.time безпосередньо з базою даних. Використовуйте драйвер JDBC, сумісний з JDBC 4.2 або новішою. Не потрібні рядки, не потрібні java.sql.*
класи. Hibernate 5 та JPA 2.2 підтримують java.time .
Де отримати класи java.time?
ZoneOffset.systemDefault()