Apollo  6.0
Open source self driving car software
time_conversion.h
Go to the documentation of this file.
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 
27 namespace apollo {
28 namespace cyber {
29 namespace 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.
47 static 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.
58 constexpr int32_t UNIX_GPS_DIFF = 315964800;
59 
60 constexpr int64_t ONE_MILLION = 1000000L;
61 
62 constexpr int64_t ONE_BILLION = 1000000000L;
63 
64 template <typename T>
65 T 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 
74 inline int64_t UnixToGpsMicroseconds(int64_t unix_microseconds) {
75  return UnixToGpsSeconds(unix_microseconds / ONE_MILLION) * ONE_MILLION +
76  unix_microseconds % ONE_MILLION;
77 }
78 
79 inline int64_t UnixToGpsNanoseconds(int64_t unix_nanoseconds) {
80  return UnixToGpsSeconds(unix_nanoseconds / ONE_BILLION) * ONE_BILLION +
81  unix_nanoseconds % ONE_BILLION;
82 }
83 
84 template <typename T>
85 T 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 
95 inline int64_t GpsToUnixMicroseconds(int64_t gps_microseconds) {
96  return GpsToUnixSeconds(gps_microseconds / ONE_MILLION) * ONE_MILLION +
97  gps_microseconds % ONE_MILLION;
98 }
99 
100 inline int64_t GpsToUnixNanoseconds(int64_t gps_nanoseconds) {
101  return GpsToUnixSeconds(gps_nanoseconds / ONE_BILLION) * ONE_BILLION +
102  gps_nanoseconds % ONE_BILLION;
103 }
104 
105 inline uint64_t GpsToUnixMicroseconds(uint64_t gps_microseconds) {
106  return GpsToUnixSeconds(gps_microseconds / ONE_MILLION) * ONE_MILLION +
107  gps_microseconds % ONE_MILLION;
108 }
109 
110 inline uint64_t GpsToUnixNanoseconds(uint64_t gps_nanoseconds) {
111  return GpsToUnixSeconds(gps_nanoseconds / ONE_BILLION) * ONE_BILLION +
112  gps_nanoseconds % ONE_BILLION;
113 }
114 
115 inline 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 
125 inline 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 int64_t ONE_MILLION
Definition: time_conversion.h:60
std::string UnixSecondsToString(uint64_t unix_seconds, const std::string &format_str="%Y-%m-%d-%H:%M:%S")
Definition: time_conversion.h:125
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
T UnixToGpsSeconds(T unix_seconds)
Definition: time_conversion.h:65
constexpr int64_t ONE_BILLION
Definition: time_conversion.h:62
constexpr int32_t UNIX_GPS_DIFF
Definition: time_conversion.h:58
int64_t GpsToUnixNanoseconds(int64_t gps_nanoseconds)
Definition: time_conversion.h:100
int64_t UnixToGpsMicroseconds(int64_t unix_microseconds)
Definition: time_conversion.h:74
int64_t GpsToUnixMicroseconds(int64_t gps_microseconds)
Definition: time_conversion.h:95
uint64_t StringToUnixSeconds(const std::string &time_str, const std::string &format_str="%Y-%m-%d %H:%M:%S")
Definition: time_conversion.h:115
int64_t UnixToGpsNanoseconds(int64_t unix_nanoseconds)
Definition: time_conversion.h:79
T GpsToUnixSeconds(T gps_seconds)
Definition: time_conversion.h:85