06、日期 相关概念

1、GMT (Greenwich Mean Time,格林尼治标准时间)


  • GMT 是指位于英国伦敦郊区的皇家格林尼治天文台标准时间
    • 因为,本初子午线 被定义为是通过那里的经线
  • GMT 的正午时间:
    • 是指当太阳横穿格林尼治子午线时(即:在格林尼治上空最高点时)的时间。

  • 由于地球在它的椭圆轨道里的运动速度不均匀
    • 时刻:可能与实际的太阳时有误差最大误差达 16 分钟
  • 由于地球每天的自转是有些不规则的,而且正在缓慢减速
    • 因此,格林尼治时间已经不再被作为标准时间 使用。

  • 现在的标准时间,是由原子钟报时协调世界时(UTC)

2、UTC (Coordinated Universal Time,协调世界时 / 世界标准时间)

  • 1967 年国际度量衡大会决定,以铯原子 跃迁 9192631770 个周期,所持续的时间长度 定义为 1 秒
  • 科研技术还在发展,精密设备和测量能力也越来越高,最新的原子钟甚至可以达到 1 亿年不差 1 秒
  • 有了原子钟,人们基于原子钟又确立了一套新的时间标准,叫做「国际原子时」(International Atomic Time,简称 TAI)。

  • UTC 是基于原子钟(国际原子时,TAI)的全球统一时间标准,通过插入 闰秒 调整以对齐地球自转
  • 时间差
    • TAI 与 UTC 的差值为整数秒,且每次 UTC 添加 闰秒 时,TAI 比 UTC 提前 1 秒
    • 截至 2024 年 1 月,TAI = UTC + 37 秒

3、CST 时间

  • CST 可以为如下 4 个不同的时区的缩写:
    • 中国标准时间(北京时间):China Standard Time UTC+8无夏令时)。
      • 在时区划分上,属东八区,比协调世界时(UTC)早 8 小时
    • 古巴标准时间:Cuba Standard Time UTC-4
    • 美国中部时间:Central Standard Time (USA) UTC-6
    • 澳大利亚中部时间:Central Standard Time (Australia) UTC+9:30
  • 注意:编程中需明确时区代码(如:Asia/Shanghai 代替 CST 避免歧义)。
    • 如:MySQL 的链接地址后边,跟上此参数(serverTimezone=Asia/Shanghai)。
url: jdbc:mysql://127.0.0.1:3306/smart?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

4、CET(Central European Time,欧洲中部时间)

  • 欧洲中部时间 是比 世界标准时间(UTC)早一个小时的时区名称之一。
    • 它被大部分欧洲国家和部分北非国家采用。
  • 冬季时间为 UTC+1,夏季欧洲夏令时为 UTC+2。

5、ISO 时间(ISO 8601 标准时间格式)

  • 国际标准化组织(ISO)制定的日期时间表示格式。
  • 格式示例
    • 完整格式2023-10-05T14:30:45+08:00(日期 + 时间 + 时区偏移)。
    • 简化格式20231005T143045+0800(无分隔符)。
  • 特点
    • 明确、无歧义,支持排序和解析。
    • 默认使用 UTC(如 2023-10-05T06:30:45ZZ 表示 UTC)。

6、时间戳(Timestamp)

  • 定义:从固定起点(Epoch)开始的时间偏移量,通常为整数浮点数
  • 常见类型
    • Unix 时间戳:秒数(自 1970-01-01T00:00:00 UTC)。
    • 毫秒级 时间戳:Java、JavaScript 常用(如:1696500000000)。
    • 纳秒级 时间戳:高性能计算场景(如:1696500000000000000)。
  • 应用场景:日志排序、缓存过期、分布式系统事件追踪。

7、NTP(Network Time Protocol,网络时间协议)

  • 定义:用于同步 计算机系统时间的协议,基于分层 时钟源(Stratum)。
  • 工作原理
    • 客户端向服务器发送时间查询请求,计算网络延迟并校准。
    • 支持误差补偿(精度可达毫秒级)。
  • 分层结构
    • Stratum 0:原子钟、GPS 时钟。
    • Stratum 1:直接连接 Stratum 0 的服务器。
    • Stratum 2:从 Stratum 1 同步的服务器(依此类推)。
  • 应用场景:服务器集群、金融交易系统、工业控制系统。

  • 校准系统时钟
<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <!-- 检查最新的版本号 -->  
    <version>3.8.0</version>
</dependency>
import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.TimeInfo;

import java.net.InetAddress;

public class NTPTimeSync {

    public static void main(String[] args) {
        // 使用公共的NTP服务器,也可以指定其他NTP服务器
        String ntpServer = "pool.ntp.org";

        try {
            NTPUDPClient client = new NTPUDPClient();
            client.open();

            InetAddress inetAddress = InetAddress.getByName(ntpServer);
            TimeInfo timeInfo = client.getTime(inetAddress);

            long returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime();
            long localTime = System.currentTimeMillis();

            long offset = returnTime - localTime;

            // 校准本地时间
            long adjustedTime = System.currentTimeMillis() + offset;
            
            // 校准前本地时间: 1747813516898
            System.out.println("校准前本地时间: " + localTime);
            // 校准后本地时间: 1747813516812
            System.out.println("校准后本地时间: " + adjustedTime);

            client.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

8、时间为什么会越走越不准?

  • 钟表和计算机内部都有一个叫做「晶体振荡器」的东西,给它加上电压,它就会以固定的频率振动
    • 这个振动频率的「稳定性」,取决于它的制造工艺,以及外界环境的影响
  • 出于成本的考虑,钟表制作工艺没那么高
    • 所以,它更容易有误差
  • 电脑制造工艺虽然比较高
    • 但它内部的晶体振荡器也会受到「温度」变化带来的影响,在工作过程中,也会有产生误差
  • 虽然它们的误差很小,但日积月累下来,误差就越来越明显

9、Unix 2038 bug(Jason hatchet bug)

  • 很多编程语言起源于 UNIX 系统,而 UNIX 系统认为 1970 年 1 月 1 日 0 点是时间纪元
    • 所以, UNIX 时间戳是以 1970 年 1 月 1 日 0 点为 计时起点时间 的。

  • 最初计算机操作系统是 32 位,而时间也是用 32 位表示。
    * Integer 在 JAVA 中用 32 位表示,因此,32 位能表示的最大值是 2147483647。
// 2147483647
System.out.println(Integer.MAX_VALUE);
  • 1 年 365 天的总秒数是 31536000 。
    • 因此, 2147483647/31536000 = 68.1,32 位能表示的最长时间68 年
  • 1970 加上 68.1,实际最终到 2038 年 01 月 19 日 03 时 14 分 07 秒,便会到达最大时间
    • 这是著名的 Unix 2038 bug(Jason hatchet bug)
  • 过了这个时间点,所有 32 位操作系统时间便会变为 10000000 00000000 00000000 00000000,
    • 算下来就是 1901 年 12 月 13 日 20 时 45 分 52 秒,便会出现 时间回归现象
      • 很多软件便会运行异常了

  • 解决方案就是,计算机表示时间使用了 64 位来代替 32 位
    • 在 64 位系统下,此时间最多可以表示到 292,277,026,596 年 12 月 4 日 15 时 30 分 08 秒。这个时间就可以非常长了,在目前的人类生活时间中,远远够用了。

10、小结

  • 存储与传输
    • 优先使用 UTC 时间ISO 8601 格式
  • 时区处理
    • 在展示时,转换为本地时间(如:ZonedDateTime in Java)。
  • 同步机制
    • 关键系统部署 NTP 客户端,选择低 Stratum 服务器。
  • 闰秒与 DST
    • 使用成熟时间库(如:java.time)自动处理复杂规则。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值