java sql日期时间

当我将SQL DateTime插入数据库时​​,我得到2007-02-07 12:00:00.00

但我像这样制作了Date对象: 2007-02-07 17:29:46.00

如何获取数据库中秒的值。 它总是将其改回12:00:00.00

 date.setYear(Integer.valueOf(parsedDate[2].replaceAll(" ", "")) - 1900); date.setMonth(Integer.valueOf(parsedDate[0].replaceAll(" ", ""))); date.setDate(Integer.valueOf(parsedDate[1].replaceAll(" ", ""))); ... java.sql.Date sqlDate = new java.sql.Date(date.getTime()); 

我应该使用任何格式化程序吗?

java.sql.Date表示日期,而不是日期和时间。 来自文档 :

为了符合SQL DATE的定义,java.sql.Date实例包含的毫秒值必须通过在与实例关联的特定时区中将小时,分钟,秒和毫秒设置为零来“标准化”。 。

如果要存储日期和时间,则应查找其他类型 – 例如java.sql.Timestamp 。 编辑:这并不是建议您使用TIMESTAMP列类型 – 正如paulsm4在评论中所说,这是另一回事。 但是,据我所知,JDBC仅支持:

  • Date (不,你也想要时间)
  • Time (不,你也要约会)
  • Timestamp (包括日期和时间,但您不希望TIMESTAMP SQL语义)

希望使用带有DATETIME列的Java Timestamp类型来工作,尽管没有Timestamp提供的精度级别。

编辑:经过一些研究,看起来你可能想要使用java.sql.Time类型,但有特殊的驱动程序参数 – 至少如果你使用的是Microsoft驱动程序。 有关更多信息,请参阅有关配置JDBC的这些文档。

TL;博士

您可能会因为不了解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

没有像DateTime这样的SQL标准类型,也没有Java中的任何类。 所以我不知道你的意图。

至于输入字符串, 2007-02-07 17:29:46.00 ,将其解析为LocalDateTime因为它缺少任何时区指示符或从UTC偏移量。

这种SQL风格的格式几乎符合ISO 8601标准。 要完全符合要求,请用T替换中间的SPACE。 在解析/生成字符串时, 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.Datejava.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 ) ; 

如何获取数据库中秒的值

不确定你的“秒值”是什么意思。

也许你想要从UTC的1970年第一时刻的纪元参考开始计算秒数。

 long secondsSinceEpoch = ldt.toEpochSecond() ; 

如果您的目标只是实例化java.sql.Date ,请不要打扰。 永远不要再使用那门课。 但是,仅供参考,您的具体问题可能是用于该类的可怕设计的副作用。 java.sql.Date类inheritance自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以了解InstantZoneIdZonedDateTime类。 搜索Stack Overflow和dba.StackExchange.com以了解SQL标准类型TIMESTAMP WITH TIME ZONE


关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。

您可以直接与数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC驱动程序 。 不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

  • Java SE 8Java SE 9Java SE 10及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6Java SE 7
    • 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
  • Android的
    • 更高版本的Android捆绑java.time类的实现。
    • 对于早期的Android(<26), ThreeTenABP项目采用ThreeTen-Backport (如上所述)。 请参见如何使用ThreeTenABP ….

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如IntervalYearWeekYearQuarter等。