ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用时间戳配合LocalDate.ofEpochDay(days)方法获取的日期不准确的问题!

2022-01-27 18:35:47  阅读:239  来源: 互联网

标签:System UTC ofEpochDay 00 days offsetMillis 时间 时区 LocalDate


 最近在使用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()有几大场景
  1. 统计耗时: 比如在一段逻辑前后获取时间戳, 并将两者差作为耗时
  2. 记录时刻: 很多时候我们不需要结构化的时间, 仅仅需要记录一个时刻, 用作后续的时刻对比或结构化
  3. 构造Date: 有时我们不得不通过一个给定的时间戳, 将它结构化为Date对象以便后续操作
  细品上面这些场景, 确实大部分场景是跟时区无关的, 所以并不会有任何影响, 而第三个场景中, 构造java.util.Date 对象时, Date的构造函数所定义的时间戳参数是基于GMT时区 而GMT是格林尼治的标准时间, 巧了, 格林尼治正好处在零时区, 所以GMT = UTC+0h 也不知道是巧合, 还是有意为之, 哈哈  

总结

写了这么久的System.currentTimeMillis(), 一直以为它返回的时间戳是基于当前系统时区(CTS), 没想到它是基于UTC的, 一度陷入沉思, 有被自己菜到, 哈哈... 需要重新系统性的学习一下Java的时间模块了!        

标签:System,UTC,ofEpochDay,00,days,offsetMillis,时间,时区,LocalDate
来源: https://www.cnblogs.com/imyjy/p/15850728.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有