[英]how to set datetime from java to sql with Date today = new Date();
我今天設置了Date = new Date(); 這個值輸入到html上,向我顯示此信息星期六5月18日22:42:32 ICT 2019
但在SQL Server中,我的值是2019-05-18 00:00:00,具有smalldatetime類型。 如何獲得日期和小時的價值?
Java類中的代碼
Date today = new Date();
Datenow dn = new Datenow();
dn.setToday(today);
dateFacade.create(dn);
在存儲數據時,您使用的是java.sql.Date
因為如果是這種情況,那么時間值將被截斷。 您必須改為使用java.sql.Timestamp
。
您正在數據庫和Java代碼中混合使用錯誤的數據類型 ,試圖代表片刻,但仍要剝離重要的區域/偏移量信息。 但是,如果您堅持:
myPreparedStatement.setObject (
… ,
OffsetDateTime.now( ZoneOffset.UTC ).toLocalDateTime() // Or some other `ZoneId` or `ZoneOffset` object.
) ;
Microsoft SQL Server中的smalldatetime
類型是非標准的傳統類型。 該文檔建議現在使用其他類型。 請注意,將來的日期僅限於2079年6月6日。
此類型僅表示日期和一天中的時間,可解析為整秒。 因此,這類型並不代表一個時刻。 如果沒有時區或UTC偏移的上下文,我們將無法確定時刻。 smalldatetime
表示大約26-27小時(全球時區范圍)內的潛在時刻。 因此,例如,2019-01-23 12:00:00可能意味着東京的中午,加爾各答的中午,巴黎的中午或蒙特利爾的中午—所有這些都是彼此不同的時刻,彼此相隔數小時。
您正在使用可怕的日期時間類( java.sql.Date
或java.util.Date
),這些日期類現在是遺留的,幾年前被JSR 310中定義的現代java.time類所取代。
Java中的smalldatetime
等效類型為LocalDateTime
,它是具有日期的日期,但沒有時區或UTC偏移量。
LocalDateTime ldt = LocalDateTime.of( 2018 , Month.MAY , 18 , 22 , 42 , 22 ) ;
使用JDBC 4.2及更高版本,我們可以直接與數據庫交換一些java.time類型。 我不使用Microsoft SQL Server,因此沒有嘗試過。 但是您應該能夠將LocalDateTime
Java對象發送到smalldatetime
列。
使用帶?
的准備好的語句 SQL代碼中的占位符。
myPreparedStatement.setObject( … , ldt ) ;
恢復。
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
今天的日期=新的Date();
首先,請注意java.util.Date
和java.sql.Date
之間的區別。 第一個代表UTC時刻。 第二個假裝代表僅日期,沒有時間,也沒有區域/偏移,但實際上它同時具有日期和區域/偏移,因為它是從另一個Date
繼承而來的,非常糟糕一個班級的設計。 您不應使用任何Date
類。
顯然,您正在嘗試在smalldatetime
列中表示當前時刻。 這是沒有道理的。 如上所述,您無法在smalldatetime
表示時刻。 因此,您不適當地混合了錯誤的類型。
我想,如果您堅持要進行,則可以偽造。
讓我們捕捉當前時刻。
Instant instant = Instant.now() ; // Capture the current moment in UTC.
JDBC 4.2不需要對Instant
支持。 因此,我們將其轉換為一個OffsetDateTime
對象,該對象在UTC自身中指定一小時零一分鍾-分鍾-秒的自UTC的偏移量。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
快捷方式:將當前時刻捕獲為OffsetDateTime
。
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
如果您正確使用了類似於SQL標准的TIMESTAMP WITH TIME ZONE
的類型的列,則可以傳遞該OffsetDateTime
。
myPreparedStatement.setObject( … , odt ) ;
但是我們需要剝離UTC偏移量信息作為黑客,以適合您的smalldatetime
列。
LocalDateTime ldt = odt.toLocalDateTime() ; // Data loss: Discarding valuable information about offset-from-UTC.
如上所述,將該LocalDateTime
對象發送到數據庫。
myPreparedStatment.setObject( … , ldt ) ;
我不建議使用的快捷方式: now
致電LocalDateTime
。 我認為在java.time API中包含方法LocalDateTime.now
是一個錯誤。 我無法想象何時打電話是合適的。 在這種情況下,這樣做會使讀者感到困惑,因為我們不知道您是否理解了試圖存儲片刻但未包含區域/偏移量信息所涉及的問題。
但是,如果您堅持我的建議:
myPreparedStatement.setObject (
… ,
LocalDateTime.now( ZoneOffset.UTC ) // Or some other `ZoneId` or `ZoneOffset` object.
) ;
java.time框架內置於Java 8及更高版本中。 這些類取代了麻煩的舊的舊式日期時間類,例如java.util.Date
, Calendar
和SimpleDateFormat
。
要了解更多信息,請參見Oracle教程 。 並在Stack Overflow中搜索許多示例和說明。 規格為JSR 310 。
現在處於維護模式的Joda-Time項目建議遷移到java.time類。
您可以直接與數據庫交換java.time對象。 使用與JDBC 4.2或更高版本兼容的JDBC驅動程序 。 不需要字符串,不需要java.sql.*
類。
在哪里獲取java.time類?
ThreeTen-Extra項目使用其他類擴展了java.time。 該項目為將來可能在java.time中添加內容提供了一個試驗場。 您可以在這里找到一些有用的類,比如Interval
, YearWeek
, YearQuarter
,和更多 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.