简短总结
你可能会感到困惑,因为你不理解java.util.Date
是一个带有时间的类型,而它的子类java.sql.Date
假装成为一个仅具有日期的类,但实际上它的时间被设置为零。非常糟糕的设计。完全避免使用这两个类。只使用java.time类。
对于数据库中的仅日期列,请将该列定义为SQL标准的DATE
类型。
myPreparedStatement.setObject(
… ,
LocalDateTime.parse( "2007-02-07 17:29:46.00".replace( " " , "T" ) )
.toLocalDate()
)
java.time
现代方法使用Java 8及更高版本中添加的
java.time类。
当我将SQL DateTime插入数据库时,我得到2007-02-07 12:00:00.00。
并不存在SQL标准类型为DateTime
,在Java中也没有这样的类。所以我不知道您的意图是什么。
至于输入字符串2007-02-07 17:29:46.00
,请将其解析为LocalDateTime
,因为它没有任何时区指示器或UTC偏移量。
那种SQL样式的格式几乎符合ISO 8601标准。要完全符合,请用T
替换中间的空格。java.time类在解析/生成字符串时默认使用ISO 8601格式。
String input = "2007-02-07 17:29:46.00".replace( " " , "T" ) ;
解析。
LocalDateTime ldt = LocalDateTime.parse( input ) ;
LocalDateTime
不代表一个时刻,也不是时间轴上的一个点。它代表了大约26-27小时范围内的潜在时刻。
标准SQL提供了一个数据类型来表示这样的值,TIMESTAMP WITHOUT TIME ZONE
。
智能对象,而不是愚蠢的字符串
你的整个方法都是错误的,纠缠文本并使用旧的日期时间类。相反,使用 java.time 对象进行交换。
从JDBC 4.2开始,您无需再使用麻烦的旧java.sql类型,如java.sql.Date
或java.sql.Timestamp
。您可以通过 setObject
/getObject
方法直接与数据库交换 java.time 对象。
myPreparedStatement.setObject( … , ldt ) ;
和检索。
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
如果您想使用仅限日期的值,请使用SQL标准类型
DATE
和Java类
LocalDate
。
LocalDate ld = ldt.toLocalDate() ;
myPreparedStatement.setObject( … , ld ) ;
如何获取数据库中的秒值
不确定您所说的“秒值”是什么意思。
也许您想要从1970年第一时刻(UTC)的
纪元参考开始计算秒数。
long secondsSinceEpoch = ldt.toEpochSecond() ;
如果您的目标仅仅是实例化一个
java.sql.Date
,那就不必费心了。永远不要再使用那个类了。但是,顺便说一句,您特定的问题可能是该类采用可怕设计的副作用。
java.sql.Date
类继承自带有时间的日期类型
java.util.Date
。
java.sql.Date
类
假装成为只有日期的值,但实际上将其时间设置为00:00:00。更糟糕的是,文档告诉我们忽略它是子类的事实。不要费心去理解它; 直接使用
java.time即可。
如果您想单独处理时间,请提取
LocalTime
对象。
LocalTime lt = ldt.toLocalTime() ;
如果你想将时间设置为零,则可能需要一个仅包含日期的值。如果是这样,请使用
LocalDate
类获取不带时间和时区的日期值。
LocalDate ld = ldt.toLocalDate() :
如果你想获取该日期的第一个时刻,调用
LocalDate::atStartOfDay
。
LocalDateTime ldtStart = ldt.toLocalDate().atStartOfDay() ;
注意:如果你想要追踪实际时刻,时间轴上的特定点,则上述所有代码都是错误的。请搜索Stack Overflow了解Instant
、ZoneId
和ZonedDateTime
类。同时搜索Stack Overflow和dba.StackExchange.com了解SQL标准类型TIMESTAMP WITH TIME ZONE
。
关于 java.time
java.time 框架已内置于 Java 8 及以上版本。这些类取代了旧的 legacy 日期和时间类,如 java.util.Date
、Calendar
和 SimpleDateFormat
等。
Joda-Time 项目现在处于 维护模式,建议迁移到 java.time 类。
要了解更多信息,请参阅 Oracle 教程。并搜索 Stack Overflow 获取许多示例和解释。规范是 JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。无需字符串,无需 java.sql.*
类。
从哪里获取 java.time 类?
ThreeTen-Extra项目通过添加额外的类扩展了java.time。该项目是java.time可能未来增加内容的试验场。您可以在这里找到一些有用的类,例如Interval
, YearWeek
, YearQuarter
,以及更多。