当我在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
答案 0 :(得分:1)
java.time.Instant.ofEpochMilli( 1_554_091_200_000L )
您已经了解到,如果您未指定日期时间类,则日期时间类会回退到隐式应用JVM当前的默认时区。这意味着您的结果在运行时可能会有所不同。更糟糕的是,您的结果在 运行时可能会有所不同,因为JVM中任何应用程序的任何线程中的任何代码都可以change that default!
!最好始终指定您想要的/期望的时区。如果对您的应用程序至关重要,请与用户确认区域。
甚至更好:专注于UTC工作。仅在业务逻辑要求或向用户展示时使用时区。
ZoneId
以Continent/Region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4个字母的缩写,例如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
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 类。
有关旧版Android和Java,请参见下面的项目符号。
java.time.Instant
类代表UTC的时刻。从内部看,这是自1970年UTC的第一刻以来的纳秒计数。
Instant instant = Instant.ofEpochMilli( 1_554_091_200_000L ) ;
ZoneId z = ZoneId.of( "America/Puerto_Rico" ) ;
ZonedDateTime zdt = instant.atZone( z )
Instant
和ZonedDateTime
代表同一时刻,时间轴上的同一点。从特定区域(时区)的人们使用的挂钟时间可以看出,同一时刻同时显示的方式有所不同。
请参阅此code run live at IdeOne.com。
instant.toString():2019-04-01T04:00:00Z
zdt.toString():2019-04-01T00:00-04:00 [美国/波多黎各]
Clock
为进行更好的测试,请将备用Clock
对象作为可选参数传递给各种方法。请参阅Clock
类以获取stuck on a certain moment或lag behind the true time或use a different cadence的时钟,例如以whole second或{{3 }}。
搜索堆栈溢出。所有这些主题已经被解决了很多次。
提示:使用标准为site:stackoverflow.com
的Internet搜索引擎,例如DuckDuckGo。 Stack Overflow中的搜索功能过时,错误且偏向于查看问题而不是答案。
whole minute框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧java.time日期时间类,例如legacy,java.util.Date
和Calendar
。
要了解更多信息,请参见SimpleDateFormat
。并在Stack Overflow中搜索许多示例和说明。规格为Oracle Tutorial。
目前位于JSR 310的Joda-Time项目建议迁移到maintenance mode类。
您可以直接与数据库交换 java.time 对象。使用符合java.time或更高版本的JDBC driver。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
答案 1 :(得分:0)
基本上发生了什么事,乔达时间使用的时区与我的测试期望的时区不同。
我通过将其添加到测试中解决了该问题。
@Before
fun setUp() {
DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getTimeZone("CET")))
}
所以现在我在运行测试的所有地方都使用相同的TimeZone