aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Willmann <daniel@totalueberwachung.de>2014-04-16 18:04:04 +0200
committerDaniel Willmann <daniel@totalueberwachung.de>2014-04-16 18:29:05 +0200
commita06d4cca3824eaa16b9b0ce426d1b7ec9b7190e3 (patch)
treea1aae4fd5c9767a03de698336932b7a7cbc5dd13
parentf48456c0d92801af43395dc9e11d1e522e52e352 (diff)
gsm0411_utils: Use timegm() in gsm340_scts
Use timegm as the hack with mktime and tz offset still doesn't work if decode happens in a different timezone than encode.
-rw-r--r--src/gsm/gsm0411_utils.c27
-rw-r--r--tests/sms/sms_test.ok18
2 files changed, 9 insertions, 36 deletions
diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c
index ad9753e6..503571e7 100644
--- a/src/gsm/gsm0411_utils.c
+++ b/src/gsm/gsm0411_utils.c
@@ -99,7 +99,7 @@ time_t gsm340_scts(uint8_t *scts)
{
struct tm tm;
uint8_t yr, tz;
- int ofs;
+ int ofs_min;
time_t timestamp;
memset(&tm, 0x00, sizeof(struct tm));
@@ -118,27 +118,18 @@ time_t gsm340_scts(uint8_t *scts)
/* according to gsm 03.40 time zone is
"expressed in quarters of an hour" */
tz = *scts++;
- ofs = gsm411_unbcdify(tz&0xf7) * 15*60;
+ ofs_min = gsm411_unbcdify(tz&0xf7) * 15;
if (tz&0x08)
- ofs = -ofs;
- /* mktime() doesn't take tm.tm_gmtoff into account. Instead, it fills this
- * field with the current timezone. Which means that the resulting time is
- * off by several hours after that. So here we're setting tm.tm_isdt to -1
- * to indicate that the tm time is local, but later we subtract the
- * offset introduced by mktime. */
- tm.tm_isdst = -1;
-
- timestamp = mktime(&tm);
+ ofs_min = -ofs_min;
+
+ /* Take into account timezone offset, timegm() can deal with
+ * values outside of the [0, 59] range */
+ tm.tm_min -= ofs_min;
+
+ timestamp = timegm(&tm);
if (timestamp < 0)
return -1;
- /* Take into account timezone offset */
- timestamp -= ofs;
-#ifdef HAVE_TM_GMTOFF_IN_TM
- /* Remove an artificial timezone offset, introduced by mktime() */
- timestamp += tm.tm_gmtoff;
-#endif
-
return timestamp;
}
diff --git a/tests/sms/sms_test.ok b/tests/sms/sms_test.ok
index 331a7779..c852b16b 100644
--- a/tests/sms/sms_test.ok
+++ b/tests/sms/sms_test.ok
@@ -28,32 +28,14 @@ Result: len(9) data(0e d0 4f 78 d9 2d 9c 0e 01 )
Result: len(12) data(14 d0 4f 78 d9 2d 9c 0e c3 e2 31 19 )
Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ UTC
Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/London
-1364691600 -> 31301310000000 -> 1364695200
-Timezone Europe/London failed at ts 1364691600
Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/Berlin
-1364695200 -> 31301320000000 -> 1364698800
-Timezone Europe/Berlin failed at ts 1364695200
Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/Athens
-1364698800 -> 31301330000000 -> 1364702400
-Timezone Europe/Athens failed at ts 1364698800
Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/Moscow
Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Canada/Central
-1362880800 -> 31300120000000 -> 1362884400
-Timezone Canada/Central failed at ts 1362880800
Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ America/New_York
-1362880800 -> 31300120000000 -> 1362884400
-Timezone America/New_York failed at ts 1362880800
Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ America/Los_Angeles
-1362880800 -> 31300120000000 -> 1362884400
-Timezone America/Los_Angeles failed at ts 1362880800
Testing SCTS generation in TZ UTC, decoding in TZ Europe/Berlin
-1364695200 -> 31301320000000 -> 1364698800
-Timezone UTC->Europe/Berlin failed at ts 1364695200
Testing SCTS generation in TZ Europe/Berlin, decoding in TZ UTC
Testing SCTS generation in TZ Europe/Berlin, decoding in TZ Canada/Central
-1362880800 -> 31300120000000 -> 1362884400
-Timezone Europe/Berlin->Canada/Central failed at ts 1362880800
Testing SCTS generation in TZ Canada/Central, decoding in TZ Europe/Berlin
-1364695200 -> 31301320000000 -> 1364698800
-Timezone Canada/Central->Europe/Berlin failed at ts 1364695200
OK