aboutsummaryrefslogtreecommitdiff
path: root/src/time
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2015-08-13 17:28:39 +0200
committerRich Felker <dalias@aerifal.cx>2015-08-14 00:47:46 +0000
commitc13f2af1fe1856e36dd1b2773cac05d5d72641dc (patch)
tree4c37476636be82f48d057379699f896433f18d9e /src/time
parente5b086e1d5fe52bf1553357ee790de86eda27bf1 (diff)
downloadmusl-c13f2af1fe1856e36dd1b2773cac05d5d72641dc.zip
musl-c13f2af1fe1856e36dd1b2773cac05d5d72641dc.tar.gz
musl-c13f2af1fe1856e36dd1b2773cac05d5d72641dc.tar.bz2
match historical behavior for tm_gmtoff member of struct tm
tm_gmtoff is a nonstandard field, but on historical systems which have this field, it stores the offset of the local time zone from GMT or UTC. this is the opposite of the POSIX extern long timezone object and the offsets used in POSIX-form TZ strings, which represent the offset from local time to UTC. previously we were storing these negated offsets in tm_gmtoff too. programs which only used this field indirectly via strftime were not affected since strftime performed the negation for presentation. however, some programs and libraries accesse tm_gmtoff directly and were obtaining negated time zone offsets.
Diffstat (limited to 'src/time')
-rw-r--r--src/time/__tz.c12
-rw-r--r--src/time/localtime_r.c2
-rw-r--r--src/time/mktime.c6
-rw-r--r--src/time/strftime.c4
4 files changed, 12 insertions, 12 deletions
diff --git a/src/time/__tz.c b/src/time/__tz.c
index 102c8bc..8b84b9b 100644
--- a/src/time/__tz.c
+++ b/src/time/__tz.c
@@ -354,9 +354,9 @@ void __secs_to_zone(long long t, int local, int *isdst, long *offset, long *oppo
size_t alt, i = scan_trans(t, local, &alt);
if (i != -1) {
*isdst = types[6*i+4];
- *offset = -(int32_t)zi_read32(types+6*i);
+ *offset = (int32_t)zi_read32(types+6*i);
*zonename = (const char *)abbrevs + types[6*i+5];
- if (oppoff) *oppoff = -(int32_t)zi_read32(types+6*alt);
+ if (oppoff) *oppoff = (int32_t)zi_read32(types+6*alt);
UNLOCK(lock);
return;
}
@@ -390,15 +390,15 @@ void __secs_to_zone(long long t, int local, int *isdst, long *offset, long *oppo
}
std:
*isdst = 0;
- *offset = __timezone;
- if (oppoff) *oppoff = dst_off;
+ *offset = -__timezone;
+ if (oppoff) *oppoff = -dst_off;
*zonename = __tzname[0];
UNLOCK(lock);
return;
dst:
*isdst = 1;
- *offset = dst_off;
- if (oppoff) *oppoff = __timezone;
+ *offset = -dst_off;
+ if (oppoff) *oppoff = -__timezone;
*zonename = __tzname[1];
UNLOCK(lock);
}
diff --git a/src/time/localtime_r.c b/src/time/localtime_r.c
index 1d43d9f..2e62c29 100644
--- a/src/time/localtime_r.c
+++ b/src/time/localtime_r.c
@@ -11,7 +11,7 @@ struct tm *__localtime_r(const time_t *restrict t, struct tm *restrict tm)
return 0;
}
__secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);
- if (__secs_to_tm((long long)*t - tm->__tm_gmtoff, tm) < 0) {
+ if (__secs_to_tm((long long)*t + tm->__tm_gmtoff, tm) < 0) {
errno = EOVERFLOW;
return 0;
}
diff --git a/src/time/mktime.c b/src/time/mktime.c
index 0ab4780..bad3f07 100644
--- a/src/time/mktime.c
+++ b/src/time/mktime.c
@@ -10,14 +10,14 @@ time_t mktime(struct tm *tm)
__secs_to_zone(t, 1, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
if (tm->tm_isdst>=0 && new.tm_isdst!=tm->tm_isdst)
- t += opp - new.__tm_gmtoff;
+ t -= opp - new.__tm_gmtoff;
- t += new.__tm_gmtoff;
+ t -= new.__tm_gmtoff;
if ((time_t)t != t) goto error;
__secs_to_zone(t, 0, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
- if (__secs_to_tm(t - new.__tm_gmtoff, &new) < 0) goto error;
+ if (__secs_to_tm(t + new.__tm_gmtoff, &new) < 0) goto error;
*tm = new;
return t;
diff --git a/src/time/strftime.c b/src/time/strftime.c
index 794fbe1..e945bb7 100644
--- a/src/time/strftime.c
+++ b/src/time/strftime.c
@@ -126,7 +126,7 @@ const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *
fmt = "%H:%M";
goto recu_strftime;
case 's':
- val = __tm_to_secs(tm) + tm->__tm_gmtoff;
+ val = __tm_to_secs(tm) - tm->__tm_gmtoff;
width = 1;
goto number;
case 'S':
@@ -178,7 +178,7 @@ const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *
return "";
}
*l = snprintf(*s, sizeof *s, "%+.2d%.2d",
- (-tm->__tm_gmtoff)/3600,
+ (tm->__tm_gmtoff)/3600,
abs(tm->__tm_gmtoff%3600)/60);
return *s;
case 'Z':