tl; д-р
java.util.Date.from( // Transfer the moment in UTC, truncating any microseconds or nanoseconds to milliseconds.
Instant.now() ; // Capture current moment in UTC, with resolution as fine as nanoseconds.
)
Хоча в цьому коді вище не було сенсу. Обидва java.util.Date
і Instant
представляють момент у UTC, завжди в UTC. Наведений вище код має такий самий ефект, як:
new java.util.Date() // Capture current moment in UTC.
Тут немає користі від використання ZonedDateTime
. Якщо у вас вже є a ZonedDateTime
, налаштуйте UTC, витягнувши a Instant
.
java.util.Date.from( // Truncates any micros/nanos.
myZonedDateTime.toInstant() // Adjust to UTC. Same moment, same point on the timeline, different wall-clock time.
)
Інша відповідь правильна
Відповідь на ssoltanid правильно звертається ваш конкретне питання, як перетворити нову школу java.time об'єкт ( ZonedDateTime
) для старої школи java.util.Date
об'єкта. Витягніть Instant
із ZonedDateTime і перейдіть до java.util.Date.from()
.
Втрата даних
Зверніть увагу , що ви будете страждати втрати даних , так як Instant
треки наносекунд , оскільки епохи в той час як java.util.Date
треки мілісекунд після епохи.
Ваше запитання та коментарі порушують інші питання.
Зберігайте сервери в UTC
Ваші сервери повинні мати свою основну ОС, встановлену на UTC, як загальну найкращу практику. JVM приймає цей параметр хост-ОС як свій часовий пояс за замовчуванням у реалізаціях Java, про які я знаю.
Вкажіть часовий пояс
Але ніколи не слід покладатися на поточний часовий пояс JVM за замовчуванням. Замість того, щоб вибрати налаштування хоста, прапор, переданий під час запуску JVM, може встановити інший часовий пояс. Ще гірше: будь-який код у будь-якому потоці будь-якої програми в будь-який момент може зателефонувати, java.util.TimeZone::setDefault
щоб змінити це значення за умовчанням!
Timestamp
Тип Кассандра
Будь-яка гідна база даних і драйвер повинні автоматично обробляти налаштування переданої дати-часу на UTC для зберігання. Я не використовую Кассандру, але, схоже, вона має певну елементарну підтримку дати та часу. У документації сказано, що його Timestamp
тип - це кількість мілісекунд від тієї ж епохи (перший момент 1970 року за UTC).
ISO 8601
Крім того, Кассандра приймає введення рядків у стандартних форматах ISO 8601 . На щастя, java.time використовує формати ISO 8601 за замовчуванням для синтаксичного аналізу / генерації рядків. Реалізація Instant
класу toString
буде працювати добре.
Точність: мілісекунда проти наносекорд
Але спочатку нам потрібно зменшити наносекундну точність ZonedDateTime до мілісекунд. Один із способів - створити свіжий миттєвий пошук, використовуючи мілісекунди. На щастя, java.time має кілька зручних методів для перетворення в мілісекунди та з них.
Приклад коду
Ось приклад коду в Java 8, оновлення 60.
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
…
Instant instant = zdt.toInstant();
Instant instantTruncatedToMilliseconds = Instant.ofEpochMilli( instant.toEpochMilli() );
String fodderForCassandra = instantTruncatedToMilliseconds.toString(); // Example: 2015-08-18T06:36:40.321Z
Або згідно з цим документом про драйвер Cassandra Java , ви можете передати java.util.Date
екземпляр (не плутати з ним java.sqlDate
). Таким чином, ви можете зробити juDate з цього instantTruncatedToMilliseconds
в коді вище.
java.util.Date dateForCassandra = java.util.Date.from( instantTruncatedToMilliseconds );
Якщо це часто робите, ви можете зробити однокласник.
java.util.Date dateForCassandra = java.util.Date.from( zdt.toInstant() );
Але було б акуратніше створити трохи корисного методу.
static public java.util.Date toJavaUtilDateFromZonedDateTime ( ZonedDateTime zdt ) {
Instant instant = zdt.toInstant();
// Data-loss, going from nanosecond resolution to milliseconds.
java.util.Date utilDate = java.util.Date.from( instant ) ;
return utilDate;
}
Зверніть увагу на різницю у всьому цьому коді, ніж у запитанні. Код запитання намагався налаштувати часовий пояс екземпляра ZonedDateTime на UTC. Але це не обов'язково. Концептуально:
ZonedDateTime = Миттєвий + ZoneId
Ми просто витягуємо миттєву частину, яка вже є в UTC (в основному в UTC, прочитайте документ класу для точних деталей).
Про java.time
Java.time каркас вбудований в Java 8 і пізніших версій. Ці класи витісняти неприємні старі застарілі класи дати і часу , такі як java.util.Date
, Calendar
, і SimpleDateFormat
.
Проект Joda-Time , який зараз перебуває в режимі обслуговування , радить перейти на класи java.time .
Щоб дізнатись більше, див. Підручник Oracle . І шукайте в Stack Overflow багато прикладів та пояснень. Специфікація - JSR 310 .
Ви можете обмінювати об'єкти java.time безпосередньо з базою даних. Використовуйте драйвер JDBC, сумісний з JDBC 4.2 або новішою. Не потрібні рядки, не потрібні java.sql.*
класи.
Де отримати класи java.time?
Проект ThreeTen-Extra розширює java.time додатковими класами. Цей проект є полігоном для можливих майбутніх доповнень до java.time. Ви можете знайти деякі корисні класи тут , такі як Interval
, YearWeek
, YearQuarter
, і більш .
java.util.Date
іjava.sql.Date
.