Ответ 1
ТЛ; др
LocalDateTime.parse( // With resolution of nanoseconds, represent the idea of a date and time somewhere, unspecified. Does *not* represent a moment, is *not* a point on the timeline. To determine an actual moment, place this date+time into context of a time zone (apply a 'ZoneId' to get a 'ZonedDateTime').
"2015-05-09 00:10:23.999750900" // A 'String' nearly in standard ISO 8601 format.
.replace( " " , "T" ) // Replace SPACE in middle with 'T' to comply with ISO 8601 standard format.
) // Returns a 'LocalDateTime' object.
Нету
Нет, вы не можете использовать SimpleDateFormat для обработки наносекунд.
Но ваша предпосылка, что...
Java не поддерживает детализацию времени свыше миллисекунд в своих шаблонах дат
… Больше не относится к Java 8, 9, 10 и более поздним версиям со встроенными классами java.time. И не совсем верно для Java 6 и Java 7, так как большая часть функциональности java.time перенесена обратно.
java.time
SimpleDateFormat
и связанные с ним классы java.util.Date
/.Calendar
теперь устарели из-за нового пакета java.time, доступного в Java 8 (Tutorial).
Новые классы java.time поддерживают наносекундное разрешение. Эта поддержка включает в себя анализ и генерацию девяти цифр доли секунды. Например, когда вы используете API-интерфейс DateTimeFormatter
java.time.format
, буква S
шаблона обозначает "долю секунды", а не "миллисекунды", и может справляться со значениями наносекунд.
Instant
Например, класс Instant
представляет момент в UTC. Его метод toString
генерирует объект String
используя стандартный формат ISO 8601. Буква Z
на конце означает UTC, произносится "Зулу".
instant.toString() // Generate a 'String' representing this moment, using standard ISO 8601 format.
2013-08-20T12: 34: 56.123456789Z
Обратите внимание, что захват текущего момента в Java 8 ограничен разрешением в миллисекундах. Классы java.time могут содержать значение в наносекундах, но могут определять текущее время только в миллисекундах. Это ограничение связано с реализацией Clock
. В Java 9 и более поздних версиях новая реализация Clock
может захватить текущий момент в более высоком разрешении, в зависимости от ограничений вашего хост-оборудования и операционной системы, обычно, по моему опыту, микросекунды.
Instant instant = Instant.now() ; // Capture the current moment. May be in milliseconds or microseconds rather than the maximum resolution of nanoseconds.
LocalDateTime
В вашем примере строки ввода 2015-05-09 00:10:23.999750900
отсутствует индикатор часового пояса или смещения от UTC. Это означает, что он не представляет момент, не является точкой на временной шкале. Вместо этого он представляет потенциальные моменты в диапазоне около 26-27 часов, в диапазоне часовых поясов по всему миру.
Сравнивает такой ввод как объект LocalDateTime
. Во-первых, замените ПРОБЕЛ в середине буквой T
чтобы соответствовать формату ISO 8601, который используется по умолчанию при разборе/генерации строк. Поэтому нет необходимости указывать шаблон форматирования.
LocalDateTime ldt =
LocalDateTime.parse(
"2015-05-09 00:10:23.999750900".replace( " " , "T" ) // Replace SPACE in middle with 'T' to comply with ISO 8601 standard format.
)
;
java.sql.Timestamp
Класс java.sql.Timestamp
также обрабатывает наносекундное разрешение, но неуклюже. Обычно лучше всего выполнять свою работу в классах java.time. Больше нет необходимости использовать Timestamp
снова, Timestamp
с JDBC 4.2 и выше.
myPreparedStatement.setObject( … , instant ) ;
И поиск.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
OffsetDateTime
Поддержка Instant
не обязательна в спецификации JDBC, но есть OffsetDateTime
. Поэтому, если вышеприведенный код не работает с вашим драйвером JDBC, используйте следующее.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
И поиск.
Instant instant = myResultSet.getObject( … , OffsetDateTime.class ).toInstant() ;
При использовании драйвера старше до 4.2 JDBC, вы можете использовать toInstant
и from
методов идти вперед и назад между java.sql.Timestamp
и java.time. Эти новые методы преобразования были добавлены в старые унаследованные классы.
О java.time
Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытеснять неприятные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, и SimpleDateFormat
.
Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.
Чтобы узнать больше, смотрите Oracle Tutorial. И поиск для многих примеров и объяснений. Спецификация JSR 310.
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*
.
Где взять классы java.time?
- Java SE 8, Java SE 9, Java SE 10 и более поздние версии
- Встроенный.
- Часть стандартного Java API с комплексной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
- Android
- Более поздние версии Android связывают реализации классов java.time.
- Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP….
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval
, YearWeek
, YearQuarter
и другие.