summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver_garmin_txt.c2
-rw-r--r--driver_oncore.c2
-rw-r--r--driver_sirf.c6
-rw-r--r--driver_superstar2.c4
-rw-r--r--driver_zodiac.c2
-rw-r--r--gps.h1
-rw-r--r--gpsutils.c30
-rw-r--r--timebase.c2
8 files changed, 40 insertions, 9 deletions
diff --git a/driver_garmin_txt.c b/driver_garmin_txt.c
index ad69578c..5d249909 100644
--- a/driver_garmin_txt.c
+++ b/driver_garmin_txt.c
@@ -322,7 +322,7 @@ gps_mask_t garmintxt_parse(struct gps_device_t * session)
session->driver.garmintxt.date.tm_sec = (int)result;
session->driver.garmintxt.subseconds = 0;
session->newdata.time =
- (timestamp_t)timegm(&session->driver.garmintxt.date) +
+ (timestamp_t)mkgmtime(&session->driver.garmintxt.date) +
session->driver.garmintxt.subseconds;
mask |= TIME_SET;
} while (0);
diff --git a/driver_oncore.c b/driver_oncore.c
index a0a53fe4..9a2808a5 100644
--- a/driver_oncore.c
+++ b/driver_oncore.c
@@ -111,7 +111,7 @@ oncore_msg_navsol(struct gps_device_t *session, unsigned char *buf,
nsec = (uint) getbeu32(buf, 11);
/*@ -unrecog */
- session->newdata.time = (timestamp_t)timegm(&unpacked_date) + nsec * 1e-9;
+ session->newdata.time = (timestamp_t)mkgmtime(&unpacked_date) + nsec * 1e-9;
/*@ +unrecog */
mask |= TIME_SET;
gpsd_report(&session->context->errout, LOG_DATA,
diff --git a/driver_sirf.c b/driver_sirf.c
index cd81b8a4..a893ef51 100644
--- a/driver_sirf.c
+++ b/driver_sirf.c
@@ -887,7 +887,7 @@ static gps_mask_t sirf_msg_geodetic(struct gps_device_t *session,
unpacked_date.tm_sec = 0;
subseconds = getbeu16(buf, 17) * 1e-3;
/*@ -compdef -unrecog */
- session->newdata.time = (timestamp_t)timegm(&unpacked_date) + subseconds;
+ session->newdata.time = (timestamp_t)mkgmtime(&unpacked_date) + subseconds;
/*@ +compdef +unrecog */
gpsd_report(&session->context->errout, LOG_PROG,
"SiRF: GND 0x29 UTC: %lf\n",
@@ -1016,7 +1016,7 @@ static gps_mask_t sirf_msg_ublox(struct gps_device_t *session,
unpacked_date.tm_sec = 0;
subseconds = ((unsigned short)getbeu16(buf, 32)) * 1e-3;
/*@ -compdef */
- session->newdata.time = (timestamp_t)timegm(&unpacked_date) + subseconds;
+ session->newdata.time = (timestamp_t)mkgmtime(&unpacked_date) + subseconds;
/*@ +compdef */
#ifdef TIMEHINT_ENABLE
if (0 == (session->driver.sirf.time_seen & TIME_SEEN_UTC_2)) {
@@ -1069,7 +1069,7 @@ static gps_mask_t sirf_msg_ppstime(struct gps_device_t *session,
unpacked_date.tm_mon = (int)getub(buf, 5) - 1;
unpacked_date.tm_year = (int)getbeu16(buf, 6) - 1900;
/*@ -compdef */
- session->newdata.time = (timestamp_t)timegm(&unpacked_date);
+ session->newdata.time = (timestamp_t)mkgmtime(&unpacked_date);
/*@ +compdef */
session->context->leap_seconds = (int)getbeu16(buf, 8);
session->context->valid |= LEAP_SECOND_VALID;
diff --git a/driver_superstar2.c b/driver_superstar2.c
index c5893afc..743d2133 100644
--- a/driver_superstar2.c
+++ b/driver_superstar2.c
@@ -99,7 +99,7 @@ superstar2_msg_navsol_lla(struct gps_device_t *session,
tm.tm_mday = (int)getub(buf, 14);
tm.tm_mon = (int)getub(buf, 15) - 1;
tm.tm_year = (int)getleu16(buf, 16) - 1900;
- session->newdata.time = (timestamp_t)timegm(&tm) + (d - tm.tm_sec);
+ session->newdata.time = (timestamp_t)mkgmtime(&tm) + (d - tm.tm_sec);
mask |= TIME_SET | PPSTIME_IS;
/* extract the local tangential plane (ENU) solution */
@@ -269,7 +269,7 @@ superstar2_msg_timing(struct gps_device_t *session, unsigned char *buf,
tm.tm_min = (int)getsb(buf, 42);
d = getled64((char *)buf, 43);
tm.tm_sec = (int)d;
- session->newdata.time = (timestamp_t)timegm(&tm);
+ session->newdata.time = (timestamp_t)mkgmtime(&tm);
session->context->leap_seconds = (int)getsb(buf, 20);
mask = TIME_SET | PPSTIME_IS;
}
diff --git a/driver_zodiac.c b/driver_zodiac.c
index c961a963..6ff24efe 100644
--- a/driver_zodiac.c
+++ b/driver_zodiac.c
@@ -167,7 +167,7 @@ static gps_mask_t handle1000(struct gps_device_t *session)
unpacked_date.tm_sec = (int)getzword(24);
subseconds = (int)getzlong(25) / 1e9;
/*@ -compdef */
- session->newdata.time = (timestamp_t)timegm(&unpacked_date) + subseconds;
+ session->newdata.time = (timestamp_t)mkgmtime(&unpacked_date) + subseconds;
/*@ +compdef */
/*@ -type @*/
session->newdata.latitude = ((long)getzlong(27)) * RAD_2_DEG * 1e-8;
diff --git a/gps.h b/gps.h
index 29e0d291..16955bc3 100644
--- a/gps.h
+++ b/gps.h
@@ -2052,6 +2052,7 @@ extern void gps_enable_debug(int, FILE *);
extern /*@observer@*/const char *gps_maskdump(gps_mask_t);
extern double safe_atof(const char *);
+extern time_t mkgmtime(register struct tm *);
extern timestamp_t timestamp(void);
extern timestamp_t iso8601_to_unix(char *);
extern /*@observer@*/char *unix_to_iso8601(timestamp_t t, /*@ out @*/char[], size_t len);
diff --git a/gpsutils.c b/gpsutils.c
index 6b72776f..b02975fe 100644
--- a/gpsutils.c
+++ b/gpsutils.c
@@ -308,6 +308,36 @@ timestamp_t timestamp(void)
#endif
}
+time_t mkgmtime(register struct tm * t)
+/* struct tm to seconds since Unix epoch */
+{
+ register int year;
+ register time_t result;
+ static const int cumdays[MONTHSPERYEAR] =
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+
+ /*@ +matchanyintegral @*/
+ year = 1900 + t->tm_year + t->tm_mon / MONTHSPERYEAR;
+ result = (year - 1970) * 365 + cumdays[t->tm_mon % MONTHSPERYEAR];
+ result += (year - 1968) / 4;
+ result -= (year - 1900) / 100;
+ result += (year - 1600) / 400;
+ if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0) &&
+ (t->tm_mon % MONTHSPERYEAR) < 2)
+ result--;
+ result += t->tm_mday - 1;
+ result *= 24;
+ result += t->tm_hour;
+ result *= 60;
+ result += t->tm_min;
+ result *= 60;
+ result += t->tm_sec;
+ if (t->tm_isdst == 1)
+ result -= 3600;
+ /*@ -matchanyintegral @*/
+ return (result);
+}
+
timestamp_t iso8601_to_unix( /*@in@*/ char *isotime)
/* ISO8601 UTC to Unix UTC */
{
diff --git a/timebase.c b/timebase.c
index 2aff11cc..7c790c06 100644
--- a/timebase.c
+++ b/timebase.c
@@ -272,7 +272,7 @@ timestamp_t gpsd_utc_resolve(/*@in@*/struct gps_device_t *session)
*/
timestamp_t t;
- t = (timestamp_t)timegm(&session->nmea.date) +
+ t = (timestamp_t)mkgmtime(&session->nmea.date) +
session->nmea.subseconds;
session->context->valid &=~ GPS_TIME_VALID;