У мене проблеми з класом Date на Java. Клас дати повертає дату локальної машини, але мені потрібна UTC-0.
Я переглянув Google і знайшов чудове рішення для JavaScript, але для Java нічого корисного.
Як отримати дату UTC + 0 у Java 8?
У мене проблеми з класом Date на Java. Клас дати повертає дату локальної машини, але мені потрібна UTC-0.
Я переглянув Google і знайшов чудове рішення для JavaScript, але для Java нічого корисного.
Як отримати дату UTC + 0 у Java 8?
Відповіді:
З Java 8 ви можете писати:
OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC);
Щоб відповісти на ваш коментар, ви можете потім перетворити його на дату (якщо ви не залежите від застарілого коду, я не бачу жодної причини) або в мільйони з епох:
Date date = Date.from(utc.toInstant());
long epochMillis = utc.toEpochSecond() * 1000;
OffsetDateTime
, ніж ZonedDateTime
враховуючи, що ми працюємо з простою зміщенням від UTC, а не повним часовим поясом?
Instant.now()
Смутні старі класи дат у часі з найдавнішими версіями Java були витіснені класами java.time, вбудованими в Java 8 і пізніші версії. Дивіться навчальний посібник Oracle . Значна частина функцій була підпорядкована на Java 6 та 7 у ThreeTen-Backport та додатково адаптована до Android у ThreeTenABP .
Instant
Позначає Instant
момент на часовій шкалі в UTC з роздільною здатністю до наносекунд .
Instant instant = Instant.now();
toString
Метод створює об'єкт типу String з текстом , що представляє значення дати і час , використовуючи один із стандартних ISO 8601 форматів.
String output = instant.toString();
2016-06-27T19: 15: 25.864Z
Instant
Клас є основним класом многокомпонентного в java.time. Це має бути ваш клас переходу під час обробки дати та часу, як правило, найкраща практика - відстежувати, зберігати та обмінювати значення дати в часі за UTC.
OffsetDateTime
Але Instant
є такі обмеження, як відсутні параметри форматування для генерації рядків в альтернативних форматах. Для більшої гнучкості перетворіть Instant
на OffsetDateTime
. Вкажіть зміщення з-за UTC . У java.time це означає ZoneOffset
об’єкт. Тут ми хочемо дотримуватися UTC (+00), щоб ми могли використовувати зручну константу ZoneOffset.UTC
.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
2016-06-27T19: 15: 25.864Z
Або пропустити Instant
клас.
OffsetDateTime.now( ZoneOffset.UTC )
Тепер із OffsetDateTime
об’єктом в руці ви можете використовувати DateTimeFormatter
для створення об'єктів String з текстом у альтернативних форматах. Переповнення стека пошуку для багатьох прикладів використання DateTimeFormatter
.
ZonedDateTime
Коли ви хочете відобразити настінні годинники для певного часового поясу, застосуйте a, ZoneId
щоб отримати ZonedDateTime
.
У цьому прикладі ми застосовуємо часовий пояс Монреаля. Влітку, за дурниць літнього часу (DST) , зона компенсується -04:00
. Тому зауважте, як час виходу на чотири години раніше на виході, 15
а не на 19
години. Instant
і те ZonedDateTime
і інше представляють той самий одночасний момент, щойно переглядається через дві різні лінзи.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
2016-06-27T15: 15: 25.864-04: 00 [Америка / Монреаль]
Хоча вам слід уникати старих класів дати-часу, якщо потрібно, ви можете конвертувати, використовуючи нові методи, додані до старих класів. Тут ми використовуємо java.util.Date.from( Instant )
і java.util.Date::toInstant
.
java.util.Date utilDate = java.util.Date.from( instant );
І йти іншим напрямком.
Instant instant= utilDate.toInstant();
Аналогічно шукайте нові методи, додані в GregorianCalendar
(підклас Calendar
) для перетворення в і з java.time.ZonedDateTime
.
Java.time каркас вбудований в Java 8 і пізніших версій. Ці класи витісняти неприємні старі застарілі класи дати і часу , такі як java.util.Date
, Calendar
, і SimpleDateFormat
.
Щоб дізнатися більше, дивіться навчальний посібник Oracle . І шукайте переповнення стека за багатьма прикладами та поясненнями. Специфікація - JSR 310 .
Проект Joda-Time , який зараз знаходиться в режимі обслуговування , радить перейти до класів java.time .
Ви можете обмінюватися об'єктами java.time безпосередньо зі своєю базою даних. Використовуйте драйвер JDBC, сумісний з JDBC 4.2 або пізнішої версії. Немає необхідності в струнах, немає потреби в java.sql.*
заняттях. Hibernate 5 & JPA 2.2 підтримують java.time .
Де отримати класи java.time?
ZonedDateTime
, не було б потрібним, оскільки всі ZoneId
відображатимуться до одного, який ZoneOffset
ми могли б просто використати OffsetDateTime
?
У java8 я би використовував Instant
клас, який вже є в UTC і з ним зручно працювати.
import java.time.Instant;
Instant ins = Instant.now();
long ts = ins.toEpochMilli();
Instant ins2 = Instant.ofEpochMilli(ts)
Крім того, ви можете використовувати наступне:
import java.time.*;
Instant ins = Instant.now();
OffsetDateTime odt = ins.atOffset(ZoneOffset.UTC);
ZonedDateTime zdt = ins.atZone(ZoneId.of("UTC"));
Повертатися до Instant
Instant ins4 = Instant.from(odt);
Instant
є НЕ за місцевим часом. За Instant
визначенням знаходиться в UTC. Тому немає необхідності в махінаціях, які бачили в цьому Відповіді, намагаючись потрапити в UTC; Instant
вже знаходиться в UTC. Дивіться мою відповідь для отримання додаткової інформації та набагато простішого коду.
У Java8 ви використовуєте новий API часу та перетворюєте миттєвий сигнал у ZonedDateTime за допомогою UTC TimeZone
1 рядкове рішення на Java 8:
public Date getCurrentUtcTime() {
return Date.from(Instant.now());
}
java.util.Date
ніколи не є місцевою машинною датою. Він завжди визначається як пропущений мілісек з 1970-01-01 щодо UTC + 00: 00. Можливо, поведінка його методуtoString()
збиває з пантелику те, що справді використовує представлення в локальному часовому поясі.