Advertisement

NTP时间戳和UTC时间戳互转及其原理

阅读量:

1.NTP时间戳

采用64位无符号定点数的形式来表示NTP时间戳。其数值代表自公历元(即1970年1月1日午夜)以来经过的时间总和。该数值由高低两部分构成:其中高位占用32位来标识整数值(以秒为单位),低位占用32位来标识微小时间间隔(相当于每个皮秒等于一万亿分之一秒)。

2.UTC时间戳(unix时间戳)

从Greenwich Mean Time(GMT)的Greenwich时间基准点即格林威治时间基准点(Greenwich Time)的日期和时刻开始计算的总秒数累积计数(记录为:YYYY-MM-DD HH:mm:ss UTC)。在程序中通常被称为utc时间戳。

3.秒一些时间单位

千分之一秒(millisecond)被定义为一种极其短暂的时间单位,并等于一秒钟的千分之一(即0.001秒),通常缩写为ms。

[微秒](microsecond)定义为一百万分之一秒(即十的负六次幂),通常表示为μs

nanoseconds, abbreviated as ns, are equivalent to one-billionth of a second (10^-9 seconds). They are also referred to as milli-picoseconds.

皮秒(picosecond)相当于纳秒的千分之一(十负十二次方秒),通常用符号ps表示

4.UTC转NTP

UTC时间戳通常采用毫秒作为计量单位。当使用秒作为单位时,则相当于将UTC的时间左移32位即可得到NTP时间戳。

第一步首先计算NTP的高32位,是多少秒。

NTP的时间基准设置于1978年更为精确的时间点上,则相对于起始时间基准NTP与UTC之间存在显著差距。具体而言,在转换为秒数时可采用公式:6 \times 6 \times 24小时再乘以(每年365天乘以差距年份加上闰日的数量)。其中,在从公元一世纪到二世纪期间共有七个闰年出现过一次额外的一天

NTP高32位就可以计算出来了等于 UTC整除1000 + 70年的秒数。

假设UTC时间戳是 n毫秒: (n / 1000) + 60 * 60 * 24 * (365 * 70 + 17)

第二步 计算NTP的低32位,是多少(232皮秒)

首先看看这个单位怎么来的。低32位代表小数部分。也就是说最大等于1秒。

而 3. 而 3. 例如,在计算机系统中使用十六进制时,默认情况下每一位代表一个 nibble(四位二进制),即四分之一字节(four-bit)。这样设计的一个重要原因是它能够更好地利用硬件资源来提高数据传输效率和减少延迟。

UTC时间中的千分位取余运算等价于n模1000运算。计算得到的结果是一个不足一秒钟的时间长度值。假设计算结果为变量m,则这个值相当于多少232皮秒?将单位从毫second转换为picosecond时,则计算公式为 m \times 1e9 picoseconds。

低32位的值就是:m * 10(9次幂) / 232

复制代码
 #define  SECOND_70_YEAR (60 * 60 * 24 * (365 * 70 + 17))

    
  
    
 unsigned long long utc2ntp(unsigned long long n)
    
 {
    
     unsigned int H32bit, L32bit;
    
     unsigned long long ntpTime;
    
     
    
     H32bit = n / 1000 + SECOND_70_YEAR;
    
     L32bit = (n % 1000) * 1000000000 / 232;
    
     ntpTime = H32bit << 32 | L32bit;
    
     return ntpTime;
    
 }

5.NTP转UTC

根据上面的UTC转NTP,很容易反推出NTP 转UTC的方法

复制代码
 unsigned long long ntp2utc(unsigned long long n)

    
 {
    
     unsigned int H32bit, L32bit;
    
     unsigned long long utcTime;
    
  
    
     H32bit = (unsigned int)(n >> 32) - SECOND_70_YEAR;
    
     L32bit = (unsigned int)(n & 0xffffffff) * 232 / 1000000000;
    
     utcTime = H32bit * 1000 + L32bit;
    
     return utcTime;
    
 }

6.上面的转换存在一定的舍弃,可以用算术位移的方法计算

为该宏提供一个简明扼要的说明:NTP低32位单位被定义为10^{12}/(2^{32})。将x毫秒转换为此单位,则需将x乘以10^{9}再除以(\frac{10^{12}}{2^{32}})。通过重新排列关系式可知,结果等于x \times ( \frac{ \text{移位} }{ 1e3 })其中\text{移位}= \texttt{算术左移等价于在二进制表示中将数值向左移动相应的位数}

复制代码
 #define  SECOND_70_YEAR (60 * 60 * 24 * (365 * 70 + 17))

    
 #define  MS_TO_NTP_lOW(x) (((unsigned long long)(x) << 32) / 1000)
    
 #define  NTP_LOW_TO_MS(x) (((unsigned long long)(x) * 1000) >> 32)
    
 unsigned long long utc2ntp(unsigned long long n)
    
 {
    
     unsigned int H32bit, L32bit;
    
     unsigned long long ntpTime;
    
     
    
     H32bit = n / 1000 + SECOND_70_YEAR;
    
     L32bit = MS_TO_NTP_lOW(n % 1000);
    
     ntpTime = H32bit << 32 | L32bit;
    
     return ntpTime;
    
 }
    
  
    
 unsigned long long ntp2utc(unsigned long long n)
    
 {
    
     unsigned int H32bit, L32bit;
    
     unsigned long long utcTime;
    
  
    
     H32bit = (unsigned int)(n >> 32) - SECOND_70_YEAR;
    
     L32bit = (unsigned int)(n & 0xffffffff);
    
     L32bit = NTP_LOW_TO_MS(L32bit);
    
     utcTime = H32bit * 1000 + L32bit;
    
     return utcTime;
    
 }

全部评论 (0)

还没有任何评论哟~