使用 joda time 时 ci 测试失败

Tests failing on ci when using joda time

当我 运行 在 CI 服务器上 运行 它们通常在我的机器上 运行 时,我的测试开始失败。我在这条线上收到断言错误

assertEquals(DateTime(1554091200000), generateNextTime())

我收到错误

java.lang.AssertionError: 
Expected :2019-04-01T00:00:00.000-04:00
Actual   :2019-03-31T20:00:00.000-04:00

基本上发生的事情是 joda time 使用的时区与我的测试所期望的不同。

我通过将这个添加到我的测试中解决了这个问题。

@Before
fun setUp() {
    DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getTimeZone("CET")))
}

所以现在我在所有地方都使用相同的时区 运行 我的测试

tl;博士

java.time.Instant.ofEpochMilli( 1_554_091_200_000L ) 

始终指定时区

您已经了解到日期时间 classes 在您未能指定时回退到隐式应用 JVM 当前的默认时区。这意味着您的结果可能会在运行时发生变化。更糟糕的是,您的结果可能 运行时发生变化,因为 JVM 中任何应用程序的任何线程中的任何代码都可以 change that default!

最好始终指定您的 desired/expected 时区。如果对您的应用至关重要,请与用户确认区域。

更好的是:专注于在 UTC 中工作。仅在业务逻辑需要或向用户展示时使用时区。

ZoneId

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

ZoneId z = ZoneId.of( "America/Montreal" ) ;  

如果你想使用 JVM 当前的默认时区,请求它并作为参数传递。如果省略,代码将变得难以阅读,因为我们不确定您是否打算使用默认值,或者您是否像许多程序员一样没有意识到这个问题。

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

乔达时间

您应该知道,优秀的 Joda-Time 项目现在处于维护模式。它的创建者 Stephen Colebourne 利用在那里学到的经验教训继续创建了 JSR 310 及其实现,即 java.time classes.

请参阅下面的项目符号以了解较旧的 Android 和 Java。

java.time.Instant class 表示 UTC 中的时刻。在内部,它是自 1970 年第一刻以来的纳秒计数(UTC)。

Instant instant = Instant.ofEpochMilli( 1_554_091_200_000L ) ;

ZoneId z = ZoneId.of( "America/Puerto_Rico" ) ;
ZonedDateTime zdt = instant.atZone( z ) 

InstantZonedDateTime都代表同一时刻,时间轴上的同一点。通过特定地区(时区)人们使用的挂钟时间可以看出,同一时刻的显示方式不同。

看到这个code run live at IdeOne.com

instant.toString(): 2019-04-01T04:00:00Z

zdt.toString(): 2019-04-01T00:00-04:00[America/Puerto_Rico]

Clock

为了更好的测试,通过替代Clock objects as the optional argument to various methods. See the Clock class to get clocks that are stuck on a certain moment, or that lag behind the true time, or use a different cadence such as incrementing at the rate of a whole second or whole minute

搜索堆栈溢出

搜索堆栈溢出。所有这些主题已经被讨论过很多次了。

提示:使用互联网搜索引擎,例如 DuckDuckGo,标准为 site:whosebug.com。 Stack Overflow 中的搜索工具贫乏、有缺陷,并且偏向于查看问题而不是答案。


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

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

从哪里获得java.time classes?