From a06d4cca3824eaa16b9b0ce426d1b7ec9b7190e3 Mon Sep 17 00:00:00 2001 From: Daniel Willmann Date: Wed, 16 Apr 2014 18:04:04 +0200 Subject: 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. --- src/gsm/gsm0411_utils.c | 27 +++++++++------------------ tests/sms/sms_test.ok | 18 ------------------ 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 -- cgit v1.2.3