其他两个答案都使用过时的类,现在被 java.time 类取代。
也许您的输入数字是从 1970 年 UTC 第一时刻的纪元开始的毫秒数 (1970-01-01T00:00:00Z)。但我没有得到你在问题中所说的结果。
long input = 1_471_906_800_000L ;
Instant instant = Instant.ofEpochMilli( input );
输入:1471906800000
即时:2016-08-22T23:00:00Z
但您预计 18/01/2017 00:00:00 的值会相差几个月。如果您的输入不是来自1970-01-01T00:00:00Z 的毫秒数,您需要编辑您的问题以指定。
如果您的预期输出有误,那么让我们继续设置时间。
如果您想要一天结束前的一秒,我建议从第二天开始减去一秒,而不是硬编码23:59:59 的时间。由于夏令时 (DST) 等异常情况,该时间可能无效。此外,除非您打算在 UTC 工作,否则您需要进入所需/预期的时区。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
提取一个LocalDate,作为没有时间和时区的仅日期值。
LocalDate ld = zdt.toLocalDate();
移到第二天。
LocalDate ldNextDay = ld.plusDays( 1 );
要求第一时间。
ZonedDateTime zdtNextDay = ldNextDay.atStartOfDay( z );
减去一秒以回到前一天。
ZonedDateTime zdtPreviousDay = zdtNextDay.minusSeconds( 1L );
但是,我怀疑您在处理日期时间值时采用了错误的方法。与其试图确定一天的结束,我强烈建议您遵循使用半开放方法来处理时间跨度的常见做法。在 Half-Open 中,开头是 inclusive 而结尾是 exclusive。
因此,一整天从一天的第一刻开始,一直持续到但不包括第二天的第一刻。这样你就可以避免最后一秒的问题或试图获得一秒的无限可分部分。
ZonedDateTime zdtDayStart = LocalDate.of( 2017 , Month.JANUARY , 18 ).atStartOfDay( 1 );
ZonedDateTime zdtDayStop = zdtDayStart.plusDays( 1 );
您可能会发现 ThreeTen-Extra 项目中的 Interval 类很有帮助。
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。