LeapSeconds.cc
Go to the documentation of this file.
1 #include <time.h>
2 #include <stdlib.h>
3 #include <utl/UTCDate.h>
4 #include <utl/LeapSeconds.h>
5 
6 using namespace utl;
7 using namespace std;
8 
9 
10 bool
11 LeapSeconds::ConvertGPSToUnix(const unsigned long gpsSecond, time_t& unixSecond)
12  const
13 {
14  bool leap = false;
15  GPSToUnixIterator low = fGPSToUnixLeaps.lower_bound(gpsSecond);
16  if (low != fGPSToUnixLeaps.end())
17  leap = (low->first == gpsSecond && low->second.first == 1);
18  --low;
19  unixSecond = fGPSEpochInUnixSeconds + gpsSecond + low->second.second;
20  return leap;
21 }
22 
23 
24 void
25 LeapSeconds::ConvertUnixToGPS(const time_t unixSecond, unsigned long& gpsSecond)
26  const
27 {
28  UnixToGPSIterator up = fUnixToGPSLeaps.upper_bound(unixSecond);
29  --up;
30  gpsSecond = unixSecond - fGPSEpochInUnixSeconds + up->second;
31 }
32 
33 
34 void
36 {
37  fGPSEpochInUnixSeconds = UTCDate::GetGPSEpoch().GetUnixSecond();
38 
39  struct DateLeap {
40  UTCDate fNextDay; // day after the leap second
41  int fLeap; // +1 or -1 correction
42  };
43 
44  /*
45  Leap second is added before this date, e.g. the 1988-Jan-1 leap
46  second extends the previous day for one second, so the last second
47  of the day is 1987-Dec-1-T23:59:60, next is 1988-Jan-1-T00:00:00.
48 
49  Do not add leap seconds before the GPS epoch (1980-Jan-6)!
50  */
51  const DateLeap leaps[] = {
52  { UTCDate(1981, UTCDate::eJul, 1), +1 },
53  { UTCDate(1982, UTCDate::eJul, 1), +1 },
54  { UTCDate(1983, UTCDate::eJul, 1), +1 },
55  { UTCDate(1985, UTCDate::eJul, 1), +1 },
56  { UTCDate(1988, UTCDate::eJan, 1), +1 },
57  { UTCDate(1990, UTCDate::eJan, 1), +1 },
58  { UTCDate(1991, UTCDate::eJan, 1), +1 },
59  { UTCDate(1992, UTCDate::eJul, 1), +1 },
60  { UTCDate(1993, UTCDate::eJul, 1), +1 },
61  { UTCDate(1994, UTCDate::eJul, 1), +1 },
62  { UTCDate(1996, UTCDate::eJan, 1), +1 },
63  { UTCDate(1997, UTCDate::eJul, 1), +1 },
64  { UTCDate(1999, UTCDate::eJan, 1), +1 },
65  { UTCDate(2006, UTCDate::eJan, 1), +1 },
66  { UTCDate(2009, UTCDate::eJan, 1), +1 },
67  { UTCDate(2012, UTCDate::eJul, 1), +1 },
68  { UTCDate(2015, UTCDate::eJul, 1), +1 },
69  { UTCDate(2017, UTCDate::eJan, 1), +1 }
70  };
71 
72  const int n = sizeof(leaps) / sizeof(DateLeap);
73 
74  int totalLeaps = 0;
75  fGPSToUnixLeaps[0] = make_pair(0, 0);
76  fUnixToGPSLeaps[0] = 0;
77 
78  for (int i = 0; i < n; ++i) {
79  const time_t unixSecond = leaps[i].fNextDay.GetUnixSecond();
80  const unsigned long gpsSecond = unixSecond - fGPSEpochInUnixSeconds + totalLeaps;
81  const int leap = leaps[i].fLeap;
82  totalLeaps += leap;
83  fGPSToUnixLeaps[gpsSecond] = make_pair(leap, -totalLeaps);
84  fUnixToGPSLeaps[unixSecond] = totalLeaps;
85  }
86 }
87 
88 
89 void
91  const
92 {
93  cout << "GPS->Unix\n";
94  for (GPSToUnixIterator it = fGPSToUnixLeaps.begin();
95  it != fGPSToUnixLeaps.end(); ++it)
96  cout << it->first << ": "
97  << it->second.first << ' ' << it->second.second << '\n';
98  cout << "Unix->GPS\n";
99  for (UnixToGPSIterator it = fUnixToGPSLeaps.begin();
100  it != fUnixToGPSLeaps.end(); ++it)
101  cout << it->first << " (" << (it->first - fGPSEpochInUnixSeconds) << "): "
102  << it->second << '\n';
103 }
104 
105 
106 void
108 {
109  const char* const tz = getenv("TZ");
110  if (tz)
111  fTZ = new string(tz);
112  setenv("TZ", "", 1);
113  tzset();
114 }
115 
116 
117 void
119 {
120  if (fTZ) {
121  setenv("TZ", fTZ->c_str(), 1);
122  delete fTZ;
123  fTZ = 0;
124  } else
125  unsetenv("TZ");
126  tzset();
127 }
std::time_t GetUnixSecond() const
Relative to Unix epoch (1 Jan 1970 00:00:00 UTC) without leap corrections.
Definition: UTCDate.h:68
UnixToGPSMap::const_iterator UnixToGPSIterator
Definition: LeapSeconds.h:35
static UTCDate GetGPSEpoch()
Definition: UTCDate.h:63
bool ConvertGPSToUnix(const unsigned long gpsSecond, time_t &unixSecond) const
returns true if the GPS second is an UTC leap second
Definition: LeapSeconds.cc:11
const double low[npar]
Definition: UnivRec.h:77
GPSToUnixMap::const_iterator GPSToUnixIterator
Definition: LeapSeconds.h:32
void Dump() const
Definition: LeapSeconds.cc:90
void ConvertUnixToGPS(const time_t unixSecond, unsigned long &gpsSecond) const
Definition: LeapSeconds.cc:25

, generated on Tue Sep 26 2023.