Odpowiedzi:
Przez Timestamp
, jak sądzę masz na myśli java.sql.Timestamp
. Zauważysz, że ta klasa ma konstruktor akceptujący long
argument. Możesz przeanalizować to za pomocą DateFormat
klasy:
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = dateFormat.parse("23/09/2007");
long time = date.getTime();
new Timestamp(time);
java.util.Date
, java.util.Calendar
i java.text.SimpleDateFormat
są teraz starsze , zastąpione przez klasy java.time wbudowane w Javę 8 i nowsze. Zobacz samouczek firmy Oracle .
A co z tym?
java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");
Co masz na myśli znacznik czasu? Jeśli masz na myśli milisekundy od epoki Uniksa:
GregorianCalendar cal = new GregorianCalendar(2007, 9 - 1, 23);
long millis = cal.getTimeInMillis();
Jeśli chcesz mieć rzeczywisty obiekt java.sql.Timestamp:
Timestamp ts = new Timestamp(millis);
Calendar.SEPTEMBER
java.sql.Timestamp.from (
LocalDate.of ( 2007 , 9 , 23 )
.atStartOfDay( ZoneId.of ( "America/Montreal" ) )
.toInstant()
)
Zaktualizujmy tę stronę, wyświetlając kod przy użyciu java.time wbudowanej w Javę 8 i nowszą.
Te nowe klasy są inspirowane przez Joda-Time , zdefiniowane przez JSR 310 i rozszerzone przez ThreeTen-Extra . Wypierają one notorycznie kłopotliwe stare klasy daty i godziny, dołączane do wczesnych wersji Javy.
W java.time Instant
jest moment na osi czasu w UTC. A ZonedDateTime
to natychmiastowa zmiana na strefę czasową ( ZoneId
).
Strefa czasowa jest tutaj kluczowa. Daty September 23, 2007
nie można przetłumaczyć na moment na osi czasu bez zastosowania strefy czasowej. Weź pod uwagę, że nowy dzień w Paryżu wstaje wcześniej niż w Montrealu, gdzie wciąż jest „wczoraj”.
Ponadto java.sql.Timestamp reprezentuje zarówno datę, jak i godzinę. Musimy więc podać godzinę, która pasuje do daty. Zakładamy, że chcesz, aby pierwsza chwila dnia była porą dnia. Zwróć uwagę, że nie zawsze jest to odpowiednia pora00:00:00.0
powodu czasu letniego i prawdopodobnie innych anomalii.
Zauważ, że w przeciwieństwie do starej klasy java.util.Date iw przeciwieństwie do Joda-Time, typy java.time mają rozdzielczość nanosekund, a nie milisekund. Jest to zgodne z rozdzielczością java.sql.Timestamp.
Zwróć uwagę, że java.sql.Timestamp ma nieprzyjemny zwyczaj niejawnego stosowania bieżącej domyślnej strefy czasowej maszyny JVM do wartości daty i godziny podczas generowania reprezentacji w postaci ciągu za pomocą tej toString
metody. Tutaj widzisz zastosowaną moją America/Los_Angeles
strefę czasową. Natomiast klasy java.time są bardziej rozsądne i korzystają ze standardowych formatów ISO 8601 .
LocalDate d = LocalDate.of ( 2007 , 9 , 23 ) ;
ZoneId z = ZoneId.of ( "America/Montreal" ) ;
ZonedDateTime zdt = d.atStartOfDay( z ) ;
Instant instant = zdt.toInstant() ;
java.sql.Timestamp ts = java.sql.Timestamp.from ( instant ) ;
Zrzuć na konsolę.
System.out.println ( "d: " + d + " = zdt: " + zdt + " = instant: " + instant + " = ts: " + ts );
Po uruchomieniu.
d: 2007-09-23 = zdt: 2007-09-23T00: 00-04: 00 [Ameryka / Montreal] = natychmiast: 2007-09-23T04: 00: 00Z = ts: 2007-09-22 21:00: 00,0
Nawiasem mówiąc, od wersji JDBC 4.2 można bezpośrednio używać typów java.time. Nie ma potrzeby java.sql.Timestamp
.
PreparedStatement.setObject
ResultSet.getObject
Struktura java.time jest wbudowana w Javę 8 i nowsze. Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak java.util.Date
, Calendar
, i SimpleDateFormat
.
Projekt Joda-Time , obecnie w trybie konserwacji , zaleca migrację do klas java.time .
Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele przykładów i wyjaśnień. Specyfikacja to JSR 310 .
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie ma potrzeby stosowania ciągów ani java.sql.*
klas.
Skąd wziąć klasy java.time?
Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak Interval
, YearWeek
, YearQuarter
, i więcej .
Możesz też wykonać następujące czynności:
// untested
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 23);// I might have the wrong Calendar constant...
cal.set(Calendar.MONTH, 8);// -1 as month is zero-based
cal.set(Calendar.YEAR, 2009);
Timestamp tstamp = new Timestamp(cal.getTimeInMillis());
Zgodnie z API konstruktor, który zaakceptowałby rok, miesiąc itd., Jest przestarzały. Zamiast tego powinieneś użyć Konstruktora, który akceptuje długie. Możesz użyć implementacji Calendar, aby utworzyć żądaną datę i uzyskać dostęp do reprezentacji czasu jako długości, na przykład za pomocą metody getTimeInMillis .
Dla kompletności również rozwiązanie z Joda-Time w wersji 2.5 i jego DateTime
klasie:
new Timestamp(new DateTime(2007, 9, 23, 0, 0, DateTimeZone.forID( "America/Montreal" )).getMillis())
DateTime
obiektu zostanie zastosowana bieżąca domyślna strefa czasowa maszyny JVM . Oznacza to, że wyniki będą się różnić w zależności od różnych komputerów lub konfiguracji systemu operacyjnego hosta lub ustawień maszyny wirtualnej. Aby uzyskać przewidywalne wyniki, przekaż strefę czasową do tego DateTime
konstruktora. Wybierz odpowiednią nazwę strefy czasowej dla swojego zamiaru. Na przykład DateTimeZone.forID( "America/Montreal" )
lub DateTimeZone.UTC
.
DateTime
obiekt o milisekundy-od-epoki. Wymień .toDate().getTime()
się .getMillis()
.
DateTimeZone.getDefault()
i przekazując wynik jako opcjonalny argument. (Nawiasem mówiąc, to Locale.getDefault()
samo dotyczy dwuznaczności opcjonalnych argumentów.)
Bardziej ogólną odpowiedzią byłoby importowanie java.util.Date
, a gdy chcesz ustawić timestamp
datę równą bieżącej, po prostu ustaw ją na równą new Date()
.