diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2002-04-18 01:23:31 +0400 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2002-04-18 01:23:31 +0400 |
commit | 10d002160949c985e6f99fb8d647d5e3c67ef554 (patch) | |
tree | 6ffe46b0b090120c2a251ffc2ce19574fb5f1dfb /newlib/libc/time/mktime.c | |
parent | a26c50352b4db457813ef86fb053bd838d310d30 (diff) |
2002-04-17 Jeff Johnston <jjohnstn@redhat.com>
* libc/include/time.h (tzset, _tzset_r): Added prototypes.
(strptime): Moved prototype to be within !__STRICT_ANSI__.
(_tzname, _daylight, _timezone): No long __CYGWIN__ only.
(tzname): Defined for all platforms.
(daylight, timezone): Defined only for CYGWIN.
* libc/sys/linux/machine/i386/crt0.c: Add call to tzset() after
environment set up.
* libc/stdlib/setenv_r.c (_setenv_r): Call tzset() if the TZ
environment variable is set.
* libc/time/Makefile.am: Add support for tzset.c, tzlock.c, and
tzset_r.c.
* libc/time/Makefile.in: Regenerated.
* libc/time/gmtime.c (gmtime): Changed to call gmtime_r.
* libc/time/gmtime_r.c (gmtime_r): Changed to call _mktm_r.
* libc/time/lcltime_r.c (lcltime_r): Ditto.
* libc/time/local.h: New local header file.
* libc/time/mktime.c (mktime): Add timezone support.
* libc/time/mktm_r.c: New file which is the common engine
for gmtime_r and lcltime_r. This code has timezone support.
* libc/time/strftime.c (strftime): Add %Z timezone support.
* libc/time/tzlock.c: New file containing timezone lock stubs.
* libc/time/tzset.c: New file containing tzset() routine.
* libc/time/tzset_r.c: New file containing _tzset_r and
internal routine for calculating timezone changes for specified year.
Diffstat (limited to 'newlib/libc/time/mktime.c')
-rw-r--r-- | newlib/libc/time/mktime.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/newlib/libc/time/mktime.c b/newlib/libc/time/mktime.c index 80478dae9..f6f080d84 100644 --- a/newlib/libc/time/mktime.c +++ b/newlib/libc/time/mktime.c @@ -47,6 +47,7 @@ ANSI C requires <<mktime>>. #include <stdlib.h> #include <time.h> +#include "local.h" #define _SEC_IN_MINUTE 60L #define _SEC_IN_HOUR 3600L @@ -156,7 +157,7 @@ mktime (tim_p) { time_t tim = 0; long days = 0; - int year; + int year, isdst; /* validate structure */ validate_structure (tim_p); @@ -200,5 +201,50 @@ mktime (tim_p) /* compute total seconds */ tim += (days * _SEC_IN_DAY); + isdst = tim_p->tm_isdst; + + if (_daylight) + { + int y = tim_p->tm_year + YEAR_BASE; + if (y == __tzyear || __tzcalc_limits (y)) + { + /* calculate start of dst in dst local time and + start of std in both std local time and dst local time */ + time_t startdst_dst = __tzrule[0].change - __tzrule[1].offset; + time_t startstd_dst = __tzrule[1].change - __tzrule[1].offset; + time_t startstd_std = __tzrule[1].change - __tzrule[0].offset; + /* if the time is in the overlap between dst and std local times */ + if (tim >= startstd_std && tim < startstd_dst) + ; /* we let user decide or leave as -1 */ + else + { + isdst = (__tznorth + ? (tim >= startdst_dst && tim < startstd_std) + : (tim >= startdst_dst || tim < startstd_std)); + /* if user committed and was wrong, perform correction */ + if ((isdst ^ tim_p->tm_isdst) == 1) + { + /* we either subtract or add the difference between + time zone offsets, depending on which way the user got it wrong */ + int diff = __tzrule[0].offset - __tzrule[1].offset; + if (!isdst) + diff = -diff; + tim_p->tm_sec += diff; + validate_structure (tim_p); + tim += diff; /* we also need to correct our current time calculation */ + } + } + } + } + + /* add appropriate offset to put time in gmt format */ + if (isdst == 1) + tim += __tzrule[1].offset; + else /* otherwise assume std time */ + tim += __tzrule[0].offset; + + /* reset isdst flag to what we have calculated */ + tim_p->tm_isdst = isdst; + return tim; } |