gpt4 book ai didi

java - 为什么Timestamp在单元测试中打印运行模型和调试模型之间的差异?

转载 作者:行者123 更新时间:2023-12-02 10:51:23 25 4
gpt4 key购买 nike

    java.sql.Date date = java.sql.Date.valueOf("1900-01-01");
//-2209017600000
System.out.println(date.getTime());
java.sql.Timestamp timestamp = new Timestamp(date.getTime());
System.out.println(timestamp);


如果直接在单元测试中运行,则结果为 1900-01-01 00:00:00.0

如果在单元测试中使用调试运行,则结果将为 1970-01-01 07:30:00.0

它如何输出 1900-01-01 00:00:00.0?它存储在哪里?

为什么不输出 1970-01-01 00:00:00.0?因为我看到Timestamp构造函数的注释说自格林尼治标准时间1970年1月1日00:00:00以来的毫秒数。负数是格林尼治标准时间1970年1月1日00:00:00之前的毫秒数。

最佳答案

tl; dr

避免使用可怕的旧日期时间类。使用java.time。 of,您看到的所有怪异行为都消失了,您的问题也没有定论。

LocalDate                 // A class to represent a date-only value, without time-of-day, without time zone. Replaces `java.sql.Date` which only pretends to be date-only but actually has both a time-of-day and a time zone.
.parse( "1900-01-01" ) // Standard ISO 8601 formatted strings are parsed directly by the *java.time* classes.
.atStartOfDay( // Let java.time determine the first moment of a day.
ZoneId.of( "Pacific/Auckland" )
) // Returns a `ZonedDateTime` object.
.toString() // Generates a `String` with text in standard ISO 8601 format, wisely extended by appending the name of the time zone in square brackets.



  1900-01-01T00:00 + 11:30 [太平洋/奥克兰]


您正在使用有关遗留日期时间类的这些问题来折磨自己。 Sun,Oracle和JCP社区几年前在采用 JSR 310时都放弃了这些课程。我建议你这样做。

切勿使用 java.sql.Date

此类是可怕的旧日期时间类的一部分,该类早在几年前就被java.time类所取代。该 java.sql.Date特别是设计错误。它扩展了 java.util.Date,而文档则告诉我们忽略该继承的事实。作为子类,它伪装成仅具有日期的值,但实际上具有从另一个 Date继承的日期时间,而后者又被错误地命名为具有日期和日期时间。此外,时区潜伏在这些类中,尽管没有任何getter或setter方法都无法访问。令人困惑?是的,一团糟。切勿使用 java.sql.Date

而是使用 java.time.LocalDate

LocalDate ld = LocalDate.parse( "1900-01-01" ) ;



  ld.toString():1900-01-01


切勿使用 java.sql.Timestamp

java.sql.Date一样, java.sql.Timestamp类在几年前被替换。使用 java.time.Instant。如果递给 Timestamp,请立即使用添加到旧类中的新转换方法进行转换。

如果要在特定日期的第一天,让 LocalDate确定。第一时刻并不总是00:00:00,所以永远不要假设。指定人们使用您关心的特定壁钟时间的地区的时区。

continent/region的格式指定 proper time zone name,例如 America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用3-4个字母的缩写,例如 ESTIST,因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;


要在UTC中查看同一时刻,请提取 InstantInstant类代表 UTC在时间轴上的时刻,分辨率为 nanoseconds(最多九(9)个十进制小数位)。

Instant instant = zdt.toInstant() ;


如果要使用UTC进行第一天的工作,请使用 OffsetDateTime

OffsetDateTime odt = ld.atOffset( ZoneOffset.UTC ) ;


转换次数

如果必须与尚未更新为java.time类的旧代码进行互操作,则可以来回转换。调用添加到旧类中的新方法。

java.sql.Timestamp ts = Timestamp.from( instant ) ;


…和…

Instant instant = ts.toInstant() ;


同上日期。

java.sql.Date d = java.sql.Date.valueOf( ld ) ;


…和…

LocalDate ld = d.toLocalDate() ;




关于java.time

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

现在位于 Joda-Time中的 maintenance mode项目建议迁移到 java.time类。

要了解更多信息,请参见 Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为 JSR 310

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

在哪里获取java.time类?


Java SE 8Java SE 9Java SE 10Java SE 11和更高版本-具有捆绑实现的标准Java API的一部分。


Java 9添加了一些次要功能和修复。

Java SE 6Java SE 7


大多数java.time功能都被反向移植到 ThreeTen-Backport中的Java 6和7。

Android


更高版本的Android捆绑了java.time类的实现。
对于较早的Android(<26), ThreeTenABP项目改编为 ThreeTen-Backport(如上所述)。请参见 How to use ThreeTenABP…



ThreeTen-Extra项目使用其他类扩展了java.time。该项目是将来可能向java.time添加内容的试验场。您可能会在这里找到一些有用的类,例如 IntervalYearWeekYearQuartermore

关于java - 为什么Timestamp在单元测试中打印运行模型和调试模型之间的差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52155951/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com