У мене проблеми з класом 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()збиває з пантелику те, що справді використовує представлення в локальному часовому поясі.