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 #pragma once
17 
18 namespace apollo {
19 namespace localization {
20 namespace msf {
21 
22 // array_size(a) returns the number of elements in a.
23 template <class T, size_t N>
24 constexpr size_t ArraySize(T (&)[N]) {
25  return N;
26 }
27 
28 // Leap seconds change every a few years. See below for details.
29 // http://www.leapsecond.com/java/gpsclock.htm
30 // http://maia.usno.navy.mil/ser7/tai-utc.dat
31 //
32 // UNIX time counts seconds since 1970-1-1, without leap seconds.
33 // GPS time counts seconds since 1980-1-6, with leap seconds.
34 // When a leap second is inserted, UNIX time is ambiguous, as shown below.
35 // UNIX date and time UNIX epoch GPS epoch
36 // 2008-12-31 23:59:59.0 1230767999.0 914803213.0
37 // 2008-12-31 23:59:59.5 1230767999.5 914803213.5
38 // 2008-12-31 23:59:60.0 1230768000.0 914803214.0
39 // 2008-12-31 23:59:60.5 1230768000.5 914803214.5
40 // 2009-01-01 00:00:00.0 1230768000.0 914803215.0
41 // 2009-01-01 00:00:00.5 1230768000.5 914803215.5
42 
43 // A table of when a leap second is inserted and cumulative leap seconds.
44 static constexpr int32_t LEAP_SECONDS[][2] = {
45  // UNIX time, leap seconds
46  // Add future leap seconds here.
47  {1483228800, 18}, // 2017-01-01
48  {1435708800, 17}, // 2015-07-01
49  {1341100800, 16}, // 2012-07-01
50  {1230768000, 15}, // 2009-01-01
51  {1136073600, 14}, // 2006-01-01
52  // We do not have any data before 2016, do we?
53 };
54 
55 // This is number of seconds that UNIX is ahead of GPS, without leap seconds.
56 constexpr int32_t UNIX_GPS_DIFF = 315964800;
57 
58 constexpr int64_t ONE_MILLION = 1000000L;
59 
60 constexpr int64_t ONE_BILLION = 1000000000L;
61 
62 template <typename T>
63 T UnixToGpsSeconds(T unix_seconds) {
64  for (size_t i = 0; i < ArraySize(LEAP_SECONDS); ++i) {
65  if (unix_seconds >= LEAP_SECONDS[i][0]) {
66  return unix_seconds - (UNIX_GPS_DIFF - LEAP_SECONDS[i][1]);
67  }
68  }
69  return static_cast<T>(0);
70 }
71 
72 inline int64_t UnixToGpsMicroSeconds(int64_t unix_microseconds) {
73  return UnixToGpsSeconds(unix_microseconds / ONE_MILLION) * ONE_MILLION +
74  unix_microseconds % ONE_MILLION;
75 }
76 
77 inline int64_t UnixToGpsNanoSeconds(int64_t unix_nanoseconds) {
78  return UnixToGpsSeconds(unix_nanoseconds / ONE_BILLION) * ONE_BILLION +
79  unix_nanoseconds % ONE_BILLION;
80 }
81 
82 template <typename T>
83 T GpsToUnixSeconds(T gps_seconds) {
84  for (size_t i = 0; i < ArraySize(LEAP_SECONDS); ++i) {
85  T result = gps_seconds + (UNIX_GPS_DIFF - LEAP_SECONDS[i][1]);
86  if (result >= LEAP_SECONDS[i][0]) {
87  return result;
88  }
89  }
90  return static_cast<T>(0);
91 }
92 
93 inline int64_t GpsToUnixMicroSeconds(int64_t gps_microseconds) {
94  return GpsToUnixSeconds(gps_microseconds / ONE_MILLION) * ONE_MILLION +
95  gps_microseconds % ONE_MILLION;
96 }
97 
98 inline int64_t GpsToUnixNanoSeconds(int64_t gps_nanoseconds) {
99  return GpsToUnixSeconds(gps_nanoseconds / ONE_BILLION) * ONE_BILLION +
100  gps_nanoseconds % ONE_BILLION;
101 }
102 
103 } // namespace msf
104 } // namespace localization
105 } // namespace apollo
constexpr size_t ArraySize(T(&)[N])
Definition: time_conversion.h:24
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
constexpr int64_t ONE_MILLION
Definition: time_conversion.h:58
int64_t UnixToGpsMicroSeconds(int64_t unix_microseconds)
Definition: time_conversion.h:72
T GpsToUnixSeconds(T gps_seconds)
Definition: time_conversion.h:83
int64_t GpsToUnixNanoSeconds(int64_t gps_nanoseconds)
Definition: time_conversion.h:98
int64_t GpsToUnixMicroSeconds(int64_t gps_microseconds)
Definition: time_conversion.h:93
int64_t UnixToGpsNanoSeconds(int64_t unix_nanoseconds)
Definition: time_conversion.h:77
T UnixToGpsSeconds(T unix_seconds)
Definition: time_conversion.h:63
constexpr int32_t UNIX_GPS_DIFF
Definition: time_conversion.h:56
constexpr int64_t ONE_BILLION
Definition: time_conversion.h:60