tl;dr
myPreparedStatement
.setObject(
… , // Specify which placeholder `?` in your SQL statement.
OffsetDateTime.now( ZoneOffset.UTC ) // Capture the current moment as seen in the wall-clock time of UTC (an offset-from-UTC of zero).
) ;
Избягвайте наследени класове дата-час
Използвате ужасни класове за дата-час, които бяха изместени преди години от java.time класове.
Никога не използвайте Date
или Timestamp
.
UTC
Уловете текущия момент в UTC. Повечето бази данни съхраняват момент в UTC. И като цяло трябва да правите по-голямата част от вашата бизнес логика, отстраняване на грешки, регистриране, съхранение и обмен на данни в UTC.
OffsetDateTime
Представете момент с отместване от UTC, като използвате подходящо наречения OffsetDateTime
клас.
Искаме самото UTC или отместване от нула. Можем да използваме константа за това, ZoneOffset.UTC
.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ) ;
JDBC 4.2
От JDBC 4.2 можем директно да обменяме java.time обекти с базата данни.
За да запазите този момент в колона от тип данни, подобен на SQL-стандарта TIMESTAMP WITH TIME ZONE
:
myPreparedStatement.setObject( … , odt ) ;
Извличане:
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime
За да представите този възстановен момент на потребителя, може да искате да го настроите в очакваната/желаната от потребителя часова зона.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Никога не разчитайте на часовата зона по подразбиране
Забележете в кода по-горе, че винаги сме задавали желаното/очаквано отместване или зона.
Ако не посочите, отместването или зоната се прилагат безшумно имплицитно. По-добре е изрично да посочите намеренията си, тъй като текущите настройки по подразбиране на вашата JVM, база данни и хост ОС са извън вашите ръце като програмист. Което означава, че кодът, разчитащ на подразбиране, ще варира в поведението си по време на изпълнение.
Java 6 и 7
Същият човек, Стивън Колборн, който ръководи JSR 310 и java.time изпълнение, както и известното Joda-Time проект, също така ръководи друг проект, ThreeTen-Backport . Повечето от java.time функционалността е обратно пренесена към Java 6 и 7 в тази библиотека с почти идентичен API.
Така че вършете цялата си работа в класовете на back-port. След това, в последния момент, конвертирайте към/от java.sql.Timestamp
чрез DateTimeUtils
клас.
Тези методи за преобразуване използват предимно Instant
обекти. Instant
е момент в UTC, винаги в UTC. Можете да коригирате от вашия OffsetDateTime
до UTC чрез извличане на Instant
. Instant
class е основният градивен клас в java.time , с OffsetDateDate
има повече гъвкавост като алтернативни шаблони за форматиране при генериране на низ. Но и двете Instant
и OffsetDateTime
представляват момент, точка от времевата линия.
Instant instant = odt.toInstant() ;
java.sql.Timestamp ts = org.threeten.bp.DateTimeUtils.toSqlTimestamp( instant ) ;
Отиване в другата посока, извличане на Timestamp
от вашата база данни, след което веднага се преобразува в Instant
.
java.sql.Timestamp ts = myResultSet.getTimestamp( … ) ;
Instant instant = org.threeten.bp.DateTimeUtils.toInstant( ts ) ;
Относно java.time
java.time
framework е вграден в 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?
- Java SE 8
, Java SE 9
, Java SE 10
, Java SE 11
, и по-късно - Част от стандартния 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
и още
.