plptools
Loading...
Searching...
No Matches
psitime.cc
Go to the documentation of this file.
1/*
2 * This file is part of plptools.
3 *
4 * Copyright (C) 2000-2002 Fritz Elfert <felfert@to.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * along with this program; if not, see <https://www.gnu.org/licenses/>.
18 *
19 */
20#include "config.h"
21
22#include "psitime.h"
23
24#include <stdint.h>
25#include <stdlib.h>
26
27#define OnePM 3600 // 13:00 offset for SIBO
28
29using namespace std;
30
32 ptzValid = false;
33 tryPsiZone();
34 setUnixNow();
35}
36
37PsiTime::PsiTime(time_t time) {
38 ptzValid = false;
39 gettimeofday(&utv, &utz);
40 setUnixTime(time);
41}
42
44 if (_ptv != 0L)
45 ptv = *_ptv;
46 if (_ptz != 0L) {
47 ptz = *_ptz;
48 ptzValid = true;
49 } else {
50 ptzValid = false;
51 tryPsiZone();
52 }
53 /* get our own timezone */
54 gettimeofday(&utv, &utz);
55 psi2unix();
56}
57
58PsiTime::PsiTime(const uint32_t _ptvHi, const uint32_t _ptvLo) {
59 ptv.tv_high = _ptvHi;
60 ptv.tv_low = _ptvLo;
61 ptzValid = false;
62 tryPsiZone();
63 /* get our own timezone */
64 gettimeofday(&utv, &utz);
65 psi2unix();
66}
67
68PsiTime::PsiTime(struct timeval *_utv, struct timezone *_utz) {
69 if (_utv != 0L)
70 utv = *_utv;
71 if (_utz != 0L)
72 utz = *_utz;
73 tryPsiZone();
74 unix2psi();
75}
76
78 utv = t.utv;
79 utz = t.utz;
80 ptv = t.ptv;
81 ptz = t.ptz;
83 tryPsiZone();
84}
85
87 tryPsiZone();
88}
89
90void PsiTime::setUnixTime(struct timeval *_utv) {
91 if (_utv != 0L)
92 utv = *_utv;
93 unix2psi();
94}
95
96void PsiTime::setUnixTime(time_t time) {
97 utv.tv_sec = time;
98 utv.tv_usec = 0;
99 unix2psi();
100}
101
103 gettimeofday(&utv, &utz);
104 unix2psi();
105}
106
107
109 if (_ptv != 0L)
110 ptv = *_ptv;
111 psi2unix();
112}
113
114void PsiTime::setPsiTime(const uint32_t _ptvHi, const uint32_t _ptvLo) {
115 ptv.tv_high = _ptvHi;
116 ptv.tv_low = _ptvLo;
117 psi2unix();
118}
119
121 if (_ptz != 0L) {
122 ptz = *_ptz;
123 ptzValid = true;
124 }
125 psi2unix();
126}
127
128struct timeval &PsiTime::getTimeval(void) {
129 return utv;
130}
131
132time_t PsiTime::getTime(void) {
133 return utv.tv_sec;
134}
135
137 return ptv;
138}
139
140uint32_t PsiTime::getPsiTimeLo(void) {
141 return ptv.tv_low;
142}
143
144uint32_t PsiTime::getPsiTimeHi(void) {
145 return ptv.tv_high;
146}
147
149 utv = t.utv;
150 utz = t.utz;
151 ptv = t.ptv;
152 ptz = t.ptz;
153 ptzValid = t.ptzValid;
154 tryPsiZone();
155 return *this;
156}
157
159 psi2unix();
160 return ((utv.tv_sec == t.utv.tv_sec) &&
161 (utv.tv_usec == t.utv.tv_usec));
162}
163
165 psi2unix();
166 if (utv.tv_sec == t.utv.tv_sec)
167 return (utv.tv_usec < t.utv.tv_usec);
168 else
169 return (utv.tv_sec < t.utv.tv_sec);
170}
171
173 psi2unix();
174 if (utv.tv_sec == t.utv.tv_sec)
175 return (utv.tv_usec > t.utv.tv_usec);
176 else
177 return (utv.tv_sec > t.utv.tv_sec);
178}
179
181 const char *fmt = "%c";
182 char buf[100];
183 strftime(buf, sizeof(buf), fmt, localtime(&t.utv.tv_sec));
184 s << buf;
185 return s;
186}
187
194#define EPOCH_DIFF 0x00dcddb30f2f8000ULL
195
196/* evalOffset()
197 * Returns the difference between the Psion's timezone and the PC's timezone, in
198 * microseconds
199 */
200static long long evalOffset(psi_timezone ptz, time_t time, bool valid) {
201 int64_t offset = 0;
202 bool flg = false;
203
204 if (valid) {
205 offset = ptz.utc_offset;
206 flg = true;
207 } else {
212 const char *offstr = getenv("PSI_TZ");
213 if (offstr != 0) {
214 char *err = 0;
215 offset = strtol(offstr, &err, 0);
216 if (err != 0 && *err != '\0') {
217 offset = 0;
218 }
219 } else {
220 flg = true;
221 }
222 }
223
224 // If all else fails, we assume that PC Timezone == Psion Timezone;
225 // offset should still be 0 at this point.
226
227 if (flg) {
228 struct tm *tm = localtime(&time);
229 offset -= tm->tm_gmtoff; // Subtract out local timezone
230 offset += 3600 * tm->tm_isdst * 2;
231 offset *= 1000000; // Turn it into microseconds
232 }
233
234 return offset;
235}
236
237void PsiTime::setSiboTime(uint32_t stime) {
238 long long micro = evalOffset(ptz, time(0), false);
239
240 micro /= 1000000;
241 utv.tv_sec = stime + OnePM + micro;
242 utv.tv_usec = 0;
243// unix2psi();
244}
245
246uint32_t PsiTime::getSiboTime(void) {
247 long long micro = evalOffset(ptz, time(0), false);
248
249 micro /= 1000000;
250 return utv.tv_sec - OnePM - micro;
251}
252
254 uint64_t micro = ptv.tv_high;
255 micro = (micro << 32) | ptv.tv_low;
256
257 /* Substract Psion's idea of UTC offset */
258 micro -= EPOCH_DIFF;
259 micro -= evalOffset(ptz, micro / 1000000, ptzValid);
260
261 utv.tv_sec = micro / 1000000;
262 utv.tv_usec = micro % 1000000;
263}
264
266 uint64_t micro = (uint64_t)utv.tv_sec * 1000000ULL + utv.tv_usec;
267
268 /* Add Psion's idea of UTC offset */
269 micro += evalOffset(ptz, utv.tv_sec, ptzValid);
270 micro += EPOCH_DIFF;
271
272 ptv.tv_low = micro & 0x0ffffffff;
273 ptv.tv_high = (micro >> 32) & 0x0ffffffff;
274}
275
277 if (ptzValid)
278 return;
279 if (PsiZone::getInstance().getZone(ptz))
280 ptzValid = true;
281}
282
284
286getInstance() {
287 if (_instance == 0L)
288 _instance = new PsiZone();
289 return *_instance;
290}
291
293 _ptzValid = false;
294}
295
297setZone(psi_timezone &ptz) {
298 _ptz = ptz;
299 _ptzValid = true;
300}
301
303getZone(psi_timezone &ptz) {
304 if (_ptzValid)
305 ptz = _ptz;
306 return _ptzValid;
307}
Psion time related utility class.
Definition: psitime.h:125
void psi2unix(void)
Definition: psitime.cc:253
bool operator==(const PsiTime &t)
Comparison operators.
Definition: psitime.cc:158
~PsiTime()
Destroys the instance.
Definition: psitime.cc:86
bool operator>(const PsiTime &t)
Definition: psitime.cc:172
struct timezone utz
Definition: psitime.h:312
uint32_t getPsiTimeHi(void)
Retrieves the instance's current value in Psion time format, low 32 bits.
Definition: psitime.cc:144
void setPsiZone(psi_timezone *_ptz)
Sets the Psion time zone of this instance.
Definition: psitime.cc:120
bool ptzValid
Definition: psitime.h:313
psi_timeval & getPsiTimeval(void)
Retrieves the instance's current value in Psion time format.
Definition: psitime.cc:136
struct timeval utv
Definition: psitime.h:311
PsiTime & operator=(const PsiTime &t)
Assignment operator.
Definition: psitime.cc:148
uint32_t getPsiTimeLo(void)
Retrieves the instance's current value in Psion time format, high 32 bits.
Definition: psitime.cc:140
uint32_t getSiboTime()
Retrieves the instance's current value in SIBO time format.
Definition: psitime.cc:246
void setUnixNow(void)
Sets the value of this instance to the current time of the Unix machine.
Definition: psitime.cc:102
bool operator<(const PsiTime &t)
Definition: psitime.cc:164
psi_timeval ptv
Definition: psitime.h:309
psi_timezone ptz
Definition: psitime.h:310
void setSiboTime(uint32_t stime)
Modifies the value of this instance.
Definition: psitime.cc:237
time_t getTime(void)
Retrieves the instance's current value in Unix time format.
Definition: psitime.cc:132
void setUnixTime(struct timeval *_utv)
Sets the value of this instance.
Definition: psitime.cc:90
PsiTime(void)
Constructs a new instance, initializing to now.
Definition: psitime.cc:31
struct timeval & getTimeval(void)
Retrieves the instance's current value in Unix time format.
Definition: psitime.cc:128
void setPsiTime(psi_timeval *_ptv)
Modifies the value of this instance.
Definition: psitime.cc:108
void tryPsiZone()
Definition: psitime.cc:276
void unix2psi(void)
Definition: psitime.cc:265
A singleton wrapper for a psi_timezone .
Definition: psitime.h:326
void setZone(psi_timezone &ptz)
Definition: psitime.cc:297
bool getZone(psi_timezone &ptz)
Retrieve the Psion time zone.
Definition: psitime.cc:303
PsiZone()
Private constructor.
Definition: psitime.cc:292
static PsiZone * _instance
This objects instance (singleton)
Definition: psitime.h:350
psi_timezone _ptz
Definition: psitime.h:360
static PsiZone & getInstance()
Retrieve the singleton object.
Definition: psitime.cc:286
bool _ptzValid
Definition: psitime.h:359
Definition: doctest.h:522
static long long evalOffset(psi_timezone ptz, time_t time, bool valid)
Definition: psitime.cc:200
ostream & operator<<(ostream &s, const PsiTime &t)
Definition: psitime.cc:180
#define OnePM
Definition: psitime.cc:27
#define EPOCH_DIFF
The difference between EPOC epoch (01.01.0001 00:00:00) and Unix epoch (01.01.1970 00:00:00) in micro...
Definition: psitime.cc:194
Holds a Psion time value.
Definition: psitime.h:41
uint32_t tv_low
The lower 32 bits.
Definition: psitime.h:75
uint32_t tv_high
The upper 32 bits.
Definition: psitime.h:79
holds a Psion time zone description.
Definition: psitime.h:85
signed long utc_offset
Definition: psitime.h:96