Apollo 10.0
自动驾驶开放平台
time_conversion.h
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 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#ifndef CYBER_COMMON_TIME_CONVERSION_H_
18#define CYBER_COMMON_TIME_CONVERSION_H_
19
20#include <cstdint>
21#include <ctime>
22#include <iostream>
23#include <string>
24#include <utility>
25#include <vector>
26
27namespace apollo {
28namespace cyber {
29namespace common {
30
31// Leap seconds change every a few years. See below for details.
32// http://www.leapsecond.com/java/gpsclock.htm
33// http://maia.usno.navy.mil/ser7/tai-utc.dat
34//
35// UNIX time counts seconds since 1970-1-1, without leap seconds.
36// GPS time counts seconds since 1980-1-6, with leap seconds.
37// When a leap second is inserted, UNIX time is ambiguous, as shown below.
38// UNIX date and time UNIX epoch GPS epoch
39// 2008-12-31 23:59:59.0 1230767999.0 914803213.0
40// 2008-12-31 23:59:59.5 1230767999.5 914803213.5
41// 2008-12-31 23:59:60.0 1230768000.0 914803214.0
42// 2008-12-31 23:59:60.5 1230768000.5 914803214.5
43// 2009-01-01 00:00:00.0 1230768000.0 914803215.0
44// 2009-01-01 00:00:00.5 1230768000.5 914803215.5
45
46// A table of when a leap second is inserted and cumulative leap seconds.
47static const std::vector<std::pair<int32_t, int32_t>> LEAP_SECONDS = {
48 // UNIX time, leap seconds
49 // Add future leap seconds here.
50 {1483228800, 18}, // 2017-01-01
51 {1435708800, 17}, // 2015-07-01
52 {1341100800, 16}, // 2012-07-01
53 {1230768000, 15}, // 2009-01-01
54 {1136073600, 14}, // 2006-01-01
55};
56
57// This is number of seconds that UNIX is ahead of GPS, without leap seconds.
58constexpr int32_t UNIX_GPS_DIFF = 315964800;
59
60constexpr int64_t ONE_MILLION = 1000000L;
61
62constexpr int64_t ONE_BILLION = 1000000000L;
63
64template <typename T>
65T UnixToGpsSeconds(T unix_seconds) {
66 for (size_t i = 0; i < LEAP_SECONDS.size(); ++i) {
67 if (unix_seconds >= LEAP_SECONDS[i].first) {
68 return unix_seconds - (UNIX_GPS_DIFF - LEAP_SECONDS[i].second);
69 }
70 }
71 return static_cast<T>(0);
72}
73
74inline int64_t UnixToGpsMicroseconds(int64_t unix_microseconds) {
75 return UnixToGpsSeconds(unix_microseconds / ONE_MILLION) * ONE_MILLION +
76 unix_microseconds % ONE_MILLION;
77}
78
79inline int64_t UnixToGpsNanoseconds(int64_t unix_nanoseconds) {
80 return UnixToGpsSeconds(unix_nanoseconds / ONE_BILLION) * ONE_BILLION +
81 unix_nanoseconds % ONE_BILLION;
82}
83
84template <typename T>
85T GpsToUnixSeconds(T gps_seconds) {
86 for (size_t i = 0; i < LEAP_SECONDS.size(); ++i) {
87 T result = gps_seconds + (UNIX_GPS_DIFF - LEAP_SECONDS[i].second);
88 if ((int32_t)result >= LEAP_SECONDS[i].first) {
89 return result;
90 }
91 }
92 return static_cast<T>(0);
93}
94
95inline int64_t GpsToUnixMicroseconds(int64_t gps_microseconds) {
96 return GpsToUnixSeconds(gps_microseconds / ONE_MILLION) * ONE_MILLION +
97 gps_microseconds % ONE_MILLION;
98}
99
100inline int64_t GpsToUnixNanoseconds(int64_t gps_nanoseconds) {
101 return GpsToUnixSeconds(gps_nanoseconds / ONE_BILLION) * ONE_BILLION +
102 gps_nanoseconds % ONE_BILLION;
103}
104
105inline uint64_t GpsToUnixMicroseconds(uint64_t gps_microseconds) {
106 return GpsToUnixSeconds(gps_microseconds / ONE_MILLION) * ONE_MILLION +
107 gps_microseconds % ONE_MILLION;
108}
109
110inline uint64_t GpsToUnixNanoseconds(uint64_t gps_nanoseconds) {
111 return GpsToUnixSeconds(gps_nanoseconds / ONE_BILLION) * ONE_BILLION +
112 gps_nanoseconds % ONE_BILLION;
113}
114
115inline uint64_t StringToUnixSeconds(
116 const std::string& time_str,
117 const std::string& format_str = "%Y-%m-%d %H:%M:%S") {
118 tm tmp_time;
119 strptime(time_str.c_str(), format_str.c_str(), &tmp_time);
120 tmp_time.tm_isdst = -1;
121 time_t time = mktime(&tmp_time);
122 return static_cast<uint64_t>(time);
123}
124
125inline std::string UnixSecondsToString(
126 uint64_t unix_seconds,
127 const std::string& format_str = "%Y-%m-%d-%H:%M:%S") {
128 std::time_t t = unix_seconds;
129 struct tm ptm;
130 struct tm* ret = localtime_r(&t, &ptm);
131 if (ret == nullptr) {
132 return std::string("");
133 }
134 uint32_t length = 64;
135 std::vector<char> buff(length, '\0');
136 strftime(buff.data(), length, format_str.c_str(), ret);
137 return std::string(buff.data());
138}
139
140} // namespace common
141} // namespace cyber
142} // namespace apollo
143
144#endif // CYBER_COMMON_TIME_CONVERSION_H_
constexpr int32_t UNIX_GPS_DIFF
int64_t GpsToUnixNanoseconds(int64_t gps_nanoseconds)
constexpr int64_t ONE_MILLION
int64_t UnixToGpsNanoseconds(int64_t unix_nanoseconds)
int64_t GpsToUnixMicroseconds(int64_t gps_microseconds)
constexpr int64_t ONE_BILLION
T UnixToGpsSeconds(T unix_seconds)
uint64_t StringToUnixSeconds(const std::string &time_str, const std::string &format_str="%Y-%m-%d %H:%M:%S")
std::string UnixSecondsToString(uint64_t unix_seconds, const std::string &format_str="%Y-%m-%d-%H:%M:%S")
int64_t UnixToGpsMicroseconds(int64_t unix_microseconds)
T GpsToUnixSeconds(T gps_seconds)
class register implement
Definition arena_queue.h:37