使用时间戳配合LocalDate.ofEpochDay(days)方法获取的日期不准确的问题!
作者:互联网
最近在使用java.time.LocalDate时踩了坑, 归根到底是对jdk中的时间操作不够清晰
踩坑场景
以下这一段代码, 你认为能正常返回结果吗? 如果不能, 那么问题在哪里?/** * 基于当前时间, 进行一定的偏移, 返回偏移后的日期 * @param offsetMillis 便宜量 (毫秒) * @return 日期 */ public static LocalDate nowLocalDate(long offsetMillis) { long time = System.currentTimeMillis(); time += offsetMillis; long days = time / TimeUnit.DAYS.toMillis(1); return LocalDate.ofEpochDay(days); }
问题描述
这一段代码, 假设参数offsetMillis为0的情况下, 在00:00~08:00这段时间返回的结果都是错误的, 是前一日的日期原理剖析
System.currentTimeMillis() 获取到的时间戳是在UTC时区下当前时间与1970年1月1日0点的毫秒差, 北京时间所处的时区为CST时区相比UTC时区早8小时 (北京时间 2022年1月27日凌晨1点时, UTC时区下为2022年1月26日下午17点, 所以获取到当前时间戳后, 必须要先+8h转换为CTS的时间戳, 再进行天数计算 事实上, 时间戳是没有时区概念的, 它指的就是从历史上的某一时刻至今所经历的时光, 这是全球统一的, 你在美国经历了2小时, 他在中国也是经历了2小时, 不会因为所处时区不同而不同 历史上的某一时刻是: 1970-01-01 00:00:00 (UTC) 由于历史时刻是以UTC时区为参照的, 所以加上时间戳以后得到的当前时间也必然是UTC时区的时间 既然时间戳是基于UTC时区的, 那么为什么我们在东八区开发过程中经常使用它, 却没有产生问题? 我们在代码中使用 System.currentTimeMillis()有几大场景- 统计耗时: 比如在一段逻辑前后获取时间戳, 并将两者差作为耗时
- 记录时刻: 很多时候我们不需要结构化的时间, 仅仅需要记录一个时刻, 用作后续的时刻对比或结构化
- 构造Date: 有时我们不得不通过一个给定的时间戳, 将它结构化为Date对象以便后续操作
总结
写了这么久的System.currentTimeMillis(), 一直以为它返回的时间戳是基于当前系统时区(CTS), 没想到它是基于UTC的, 一度陷入沉思, 有被自己菜到, 哈哈... 需要重新系统性的学习一下Java的时间模块了!标签:System,UTC,ofEpochDay,00,days,offsetMillis,时间,时区,LocalDate 来源: https://www.cnblogs.com/imyjy/p/15850728.html