Skróć do mikrosekund
Oczywiście nie możemy wycisnąć nanosekund
rozdzielczość Instant
w mikrosekundy
rozdzielczość typów danych MySQL DateTime
i Timestamp
.
Chociaż nie używam MySQL, wyobrażam sobie sterownik JDBC
jest zbudowany tak, aby ignorować nanosekundy podczas odbierania Instant
, obcinając wartość do mikrosekund. Proponuję spróbować eksperymentu, aby zobaczyć i być może zbadać kod źródłowy sterownika, który jest zgodny z JDBC 4.2 i nowszymi.
Instant instant = Instant.now().with( ChronoField.NANO_OF_SECOND , 123_456_789L ) ; //Set the fractional second to a spefic number of nanoseconds.
myPreparedStatement.setObject( … , instant ) ;
…i…
Instant instant2 = myResultSet.getObject( … , Instant.class ) ;
specyfikacja JDBC 4.2
wymaga obsługi OffsetDateTime
ale, co dziwne, nie wymaga dwóch częściej używanych typów, Instant
i ZonedDateTime
. Jeśli Twój sterownik JDBC
nie obsługuje Instant
, przekonwertuj.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ; // Use `OffsetDateTime` if your JDBC driver does not support `Instant`.
Instant instant2 = odt.toInstant() ; // Convert from `OffsetDateTime` to `Instant`.
Następnie porównaj.
Boolean result = instant.equals( instant2 ) ;
System.out.println( "instant: " + instant + " equals instant2: = " + instant2 + " is: " + result ) ;
Mądrze obawiasz się, że wartości pobierane z bazy danych nie pasują do oryginalnej wartości. Jednym z rozwiązań, jeśli jest to akceptowalne dla Twojego problemu biznesowego, jest skrócenie dowolnych nanosekund do mikrosekund w oryginalnych danych. Generalnie polecam to podejście.
java.time zajęcia oferują truncatedTo
metoda. Przekaż ChronoUnit
obiekt enum, aby określić szczegółowość. W tym przypadku byłoby to ChronoUnit.MICROS
.
Instant instant = Instant().now().truncatedTo( ChronoUnit.MICROS ) ;
Obecnie to podejście powinno wystarczyć, ponieważ jest mało prawdopodobne, aby Twoje dane zawierały nanosekundy. O ile mi wiadomo, komputery głównego nurtu nie mają zegarów sprzętowych zdolnych do przechwytywania nanosekund.
Odliczanie od epoki
Jeśli nie możesz sobie pozwolić na utratę jakichkolwiek danych nanosekundowych, które mogą być obecne, użyj liczenia od epoki.
Zwykle odradzam śledzenie daty i czasu jako liczby od daty odniesienia epoki. Ale masz kilka innych możliwości przechowywania wartości opartych na nanosekundach w bazie danych, takich jak MySQL i Postgres, ograniczonych do wartości opartych na mikrosekundach.
Przechowuj parę liczb całkowitych
Zamiast korzystać z niezwykle dużej liczby nanosekund od epoki, takiej jak 1970-01-01T00:00Z, sugeruję podejście przyjęte przez wewnętrzne elementy Instant
klasa:Użyj pary liczb.
Przechowuj kilka całości sekund jako liczba całkowita w Twojej bazie danych. W drugiej kolumnie zapisz jako liczbę całkowitą liczbę nanosekund w ułamku sekundy.
Możesz łatwo wyodrębnić/wstrzyknąć te liczby z/do Instant
obiekt. Tylko proste 64-bitowe long
liczby są zaangażowane; nie ma potrzeby używania BigDecimal
lub BigInteger
. Przypuszczam, że możesz użyć 32-bitowej kolumny liczb całkowitych dla co najmniej jednej z dwóch liczb. Ale wybrałbym 64-bitowe typy kolumn całkowitych dla uproszczenia i bezpośredniej zgodności z java.time.Instant
para długich spodni klasy.
long seconds = instant.getEpochSecond() ;
long nanos = instant.getNano() ;
…i…
Instant instant = Instant.ofEpochSecond( seconds , nanos ) ;
Podczas sortowania chronologicznego musisz wykonać sortowanie wielopoziomowe, najpierw sortując według całej kolumny sekund, a następnie sortując wtórnie według ułamka sekundy w nanos.