Apollo 10.0
自动驾驶开放平台
time_conversion.h
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
17// Converts GPS timestamp from/to UNIX system timestamp.
18// This helper is considering leap second.
19
20#pragma once
21
22#include <stdint.h>
23
25
26namespace apollo {
27namespace drivers {
28namespace util {
29
30// File expires on: December 2017
31
32// There's two concept about 'time'.
33// 1. Unix time : It counts seconds since Jan 1,1970.
34// Unix time doesn't include the leap seconds.
35//
36// 2. GPS time : It counts seconds since Jan 6,1980.
37// GPS time does include the leap seconds.
38//
39// Leap seconds was added in every a few years, See details:
40// http://tycho.usno.navy.mil/leapsec.html
41// https://en.wikipedia.org/wiki/Leap_second
42//
43
44/* leap_seconds table since 1980.
45 +======+========+========+======+========+========+
46 | Year | Jun 30 | Dec 31 | Year | Jun 30 | Dec 31 |
47 +======+========+========+======+========+========+
48 | 1980 | (already +19) | 1994 | +1 | 0 |
49 +------+--------+--------+------+--------+--------+
50 | 1981 | +1 | 0 | 1995 | 0 | +1 |
51 +------+--------+--------+------+--------+--------+
52 | 1982 | +1 | 0 | 1997 | +1 | 0 |
53 +------+--------+--------+------+--------+--------+
54 | 1983 | +1 | 0 | 1998 | 0 | +1 |
55 +------+--------+--------+------+--------+--------+
56 | 1985 | +1 | 0 | 2005 | 0 | +1 |
57 +------+--------+--------+------+--------+--------+
58 | 1987 | 0 | +1 | 2008 | 0 | +1 |
59 +------+--------+--------+------+--------+--------+
60 | 1989 | 0 | +1 | 2012 | +1 | 0 |
61 +------+--------+--------+------+--------+--------+
62 | 1990 | 0 | +1 | 2015 | +1 | 0 |
63 +------+--------+--------+------+--------+--------+
64 | 1992 | +1 | 0 | 2016 | 0 | +1 |
65 +------+--------+--------+------+--------+--------+
66 | 1993 | +1 | 0 | 2017 | 0 | 0 |
67 +------+--------+--------+------+--------+--------+
68
69 Current TAI - UTC = 37. (mean that: 2017 - 1970/01/01 = 37 seconds)
70*/
71
72// We build a lookup table to describe relationship that between UTC and
73// Leap_seconds.
74//
75// Column1: UTC time diff (second).
76// Shell Example:
77// date +%s -d"Jan 1, 2017 00:00:00"
78// return 1483257600.
79//
80// date +%s -d"Jan 1, 1970 00:00:00"
81// return 28800.
82//
83// The diff between 1970/01/01 and 2017/01/01 is 1483228800.
84// (1483257600-28800)
85//
86// Column2: Leap seconds diff with GPS basetime(Jan 6,1980).
87// We Know that The leap_seconds have been already added 37 seconds
88// util now(2017).
89// So we can calculate leap_seconds diff between GPS (from Jan 6,1980)
90// and UTC time.
91
92// calc with the formula.
93static const int32_t LEAP_SECONDS[][2] = {
94 {1483228800, 18}, // 2017/01/01
95 {1435708800, 17}, // 2015/07/01
96 {1341100800, 16}, // 2012/07/01
97 {1230768000, 15}, // 2009/01/01
98 {1136073600, 14}, // 2006/01/01
99 {915148800, 13}, // 1999/01/01
100 {867711600, 12}, // 1997/07/01
101 {820480320, 11}, // 1996/01/01 ;)
102 //....
103 //..
104 // etc.
105};
106
107// seconds that UNIX time afront of GPS, without leap seconds.
108
109// Shell:
110// time1 = date +%s -d"Jan 6, 1980 00:00:00"
111// time2 = date +%s -d"Jan 1, 1970 00:00:00"
112// dif_tick = time1-time2
113// 315964800 = 315993600 - 28800
114
115const int32_t GPS_AND_SYSTEM_DIFF_SECONDS = 315964800;
116
117template <typename T>
118T unix2gps(const T unix_seconds) {
119 for (size_t i = 0; i < array_size(LEAP_SECONDS); ++i) {
120 if (unix_seconds >= LEAP_SECONDS[i][0]) {
121 return unix_seconds - (GPS_AND_SYSTEM_DIFF_SECONDS - LEAP_SECONDS[i][1]);
122 }
123 }
124 return static_cast<T>(0);
125}
126
127template <typename T>
128T gps2unix(const T gps_seconds) {
129 for (size_t i = 0; i < array_size(LEAP_SECONDS); ++i) {
130 T result = gps_seconds + (GPS_AND_SYSTEM_DIFF_SECONDS - LEAP_SECONDS[i][1]);
131 if (result >= LEAP_SECONDS[i][0]) {
132 return result;
133 }
134 }
135 return static_cast<T>(0);
136}
137
138} // namespace util
139} // namespace drivers
140} // namespace apollo
T unix2gps(const T unix_seconds)
const int32_t GPS_AND_SYSTEM_DIFF_SECONDS
T gps2unix(const T gps_seconds)
class register implement
Definition arena_queue.h:37
constexpr size_t array_size(T(&)[N])
Definition macros.h:61