拨开时间的迷雾( 二 )


  • 问题2:客户问这个问题 , 十有八九是以为时区只影响时间 , 忘记了“日期变更线” , 可以举一个极端的例子 , 举例子的时候时间一定要带上时区 。
2019-01-01 23:59:59 UTC+8到2019-01-02 00:00:00 UTC+8,中间差一天;如果转换时区到UTC+7 , 就变成了2019-01-01 22:59:59 UTC+7到2019-01-01 23:00:00 UTC+7 , 中间差0天了 。
拨开时间的迷雾
本文插图
  • 问题3:这个问题非常有挑战 , 用户都说到“数据库”了 。 看起来不把时间戳讲一讲是搞不定了 , 实际上客户真的不太理解时间戳 。 时间戳、绝对时间都非常的技术 , 客户接受不了 。 当需要表达时间戳的时候 , 我一般说成是格林尼治时间 , 我们把所有时间都转换成0时区的时间保存了 , 这样比较方便比较 。
客户追问:把本地时间和时区放在一起得到的数据 , 这个数据里面一定有时区呀?
答:这个过程就像2+8=10 , 但是通过10 , 无法找到2和8 。 计算机在存储绝对时间时做了类似的事情 。
总结下来和客户沟通的主要手段就是:统一语言加举例子 。
程序员的时间
常见问题
1.java.util.TimeZone和java.time.ZoneId , 这两个东西干什么的?有什么区别?
  • TimeZone是JDK7以前的原生时区 , ZoneId是JDK8以后的原生时区 。 他们功能是一样的 , ZoneId是从joda-time到jdk里面来踢场子的 。
  • TimeZone提供了toZoneId() , ZoneId没有提供toTimeZone() , 但是TimeZone提供了getTimeZone(ZoneId),看来ZoneId比TimeZone更为基础 , 推荐使用ZoneId 。
2.Australia/Canberra 和 UTC+11:00有什么区别?
  • 在提到时区的时候 , 我们会想到Australia/Canberra或者UTC+11:00 , 但是这两个东西并不等价 。 UTC+11:00其实是偏移量 , 与任何国家不相干 , 对应固定的经度区间,157度30分~172度30分;Australia/Canberra是行政时区 , 采用相同时区的地区 , 在地理位置上的偏移量可能不同 , 中国跨越了5个时区 , 但是全国还是统一使用UTC+8;有些国家的政策也可能调整 , 具体的偏移量也会变 , 采用夏令时的地区每年都会变 , 具体什么时间调整也是政策决定的 。
OffsetDateTime对应UTC+11:00 , 固定偏移量;ZonedDateTime对应Australia/Canberra , 偏移量不一定是固定的 , 对于Australia/Canberra一般是UTC+11 , 有时也会变成UTC+10 。
  • 下面demo中同一个Zone的两个时间2015-10-04 01:00和2015-10-04 03:00 , 使用了不同的时区 , 看起来相差两小时 , 实际上仅仅相差1小时 。
ZoneId zoneId = ZoneId.of(''Australia/Canberra''); ZonedDateTime start = LocalDateTime.of(2015, 10, 4, 1, 0) .atZone(zoneId); ZonedDateTime end = LocalDateTime.of(2015, 10, 4, 3, 0) .atZone(zoneId); System.out.println(MessageFormat.format(''Start:t{0}nEnd:t{1}nDuration:t{2}'', start, end, Duration.between(start, end)));输出结果为
Start:2015-10-04T01:00+10:00[Australia/Canberra] End:2015-10-04T03:00+11:00[Australia/Canberra] Duration:PT1H所以使用类似Australia/Canberra的这种ZoneRegion才能得到真正可靠的本地时间 。
3.ZonedDateTime vs OffsetDateTime