From 5b9f9e328d8c1f4c9ea2a5d4b2d54dc5aed6d276 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 9 Sep 1997 12:44:00 +0000 Subject: Update --- time/README | 4 +- time/africa | 81 +---------------------------------------- time/europe | 44 +++++++++++----------- time/gmtime.c | 29 +++++++-------- time/iso3166.tab | 4 ++ time/localtime.c | 99 +++++++------------------------------------------- time/northamerica | 7 +++- time/southamerica | 6 ++- time/strftime.c | 1 - time/tzfile.c | 26 +++++++------ time/tzset.c | 107 ++++++++++++++++++++++++++++++++++++++++++------------ time/zone.tab | 2 +- 12 files changed, 165 insertions(+), 245 deletions(-) (limited to 'time') diff --git a/time/README b/time/README index 99d14db152..c189555c40 100644 --- a/time/README +++ b/time/README @@ -3,7 +3,7 @@ The source files `zdump.c' `tzselect.ksh' `checktab.awk' -come from the tzcode1997a package by Arthur David Olsen et.al. +come from the tzcode1997g package by Arthur David Olsen et.al. The files `africa' @@ -25,4 +25,4 @@ The files `zone.tab' `leapseconds' `yearistype' -come from the tzdata1997a package by Arthur David Olsen et.al. +come from the tzdata1997h package by Arthur David Olsen et.al. diff --git a/time/africa b/time/africa index 2ea89bd5e0..5c9608ceaa 100644 --- a/time/africa +++ b/time/africa @@ -1,4 +1,4 @@ -# @(#)africa 7.18 +# @(#)africa 7.19 # This data is by no means authoritative; if you think you know better, # go ahead and edit the file (and please send any changes to @@ -27,85 +27,6 @@ # Derek Howse, Greenwich time and the discovery of the longitude, # Oxford University Press (1980). # -# I added so many Zone names that the old, mostly flat name space was unwieldy. -# So I renamed the Zones to have the form AREA/LOCATION, where -# AREA is the name of a continent or ocean, and -# LOCATION is the name of a specific location within that region. -# For example, the old zone name `Egypt' is now `Africa/Cairo'. -# -# Here are the general rules I used for choosing location names, -# in decreasing order of importance: -# -# Use only valid Posix file names. Use only Ascii letters, digits, `.', -# `-' and `_'. Do not exceed 14 characters or start with `-'. -# E.g. prefer `Brunei' to `Bandar_Seri_Begawan'. -# Include at least one location per time zone rule set per country. -# One such location is enough. -# If all the clocks in a country's region have agreed since 1970, -# don't bother to include more than one location -# even if subregions' clocks disagreed before 1970. -# Otherwise these tables would become annoyingly large. -# If a name is ambiguous, use a less ambiguous alternative; -# e.g. many cities are named San Jose and Georgetown, so -# prefer `Costa_Rica' to `San_Jose' and `Guyana' to `Georgetown'. -# Keep locations compact. Use cities or small islands, not countries -# or regions, so that any future time zone changes do not split -# locations into different time zones. E.g. prefer `Paris' -# to `France', since France has had multiple time zones. -# Use traditional English spelling, e.g. prefer `Rome' to `Roma', and -# prefer `Athens' to the true name (which uses Greek letters). -# The Posix file name restrictions encourage this rule. -# Use the most populous among locations in a country's time zone, -# e.g. prefer `Shanghai' to `Beijing'. Among locations with -# similar populations, pick the best-known location, -# e.g. prefer `Rome' to `Milan'. -# Use the singular form, e.g. prefer `Canary' to `Canaries'. -# Omit common suffixes like `_Islands' and `_City', unless that -# would lead to ambiguity. E.g. prefer `Cayman' to -# `Cayman_Islands' and `Guatemala' to `Guatemala_City', -# but prefer `Mexico_City' to `Mexico' because the country -# of Mexico has several time zones. -# Use `_' to represent a space. -# Omit `.' from abbreviations in names, e.g. prefer `St_Helena' -# to `St._Helena'. -# -# For time zone abbreviations like `EST' I used the following rules, -# in decreasing order of importance: -# -# Use abbreviations that consist of 3 or more upper-case Ascii letters, -# except use "___" for locations while uninhabited. -# Posix.1 requires at least 3 characters, and the restriction to -# upper-case Ascii letters follows most traditions. -# Previous editions of this database also used characters like -# ' ' and '?', but these characters have a special meaning to -# the shell and cause commands like -# set `date` -# to have unexpected effects. In theory, the character set could -# be !%./@A-Z^_a-z{}, but these tables use only upper-case -# Ascii letters (and "___"). -# Use abbreviations that are in common use among English-speakers, -# e.g. `EST' for Eastern Standard Time in North America. -# We assume that applications translate them to other languages -# as part of the normal localization process; for example, -# a French application might translate `EST' to `HNE'. -# For zones whose times are taken from a city's longitude, use the -# traditional xMT notation, e.g. `PMT' for Paris Mean Time. -# The only name like this in current use is `GMT'. -# If there is no common English abbreviation, abbreviate the English -# translation of the usual phrase used by native speakers. -# If this is not available or is a phrase mentioning the country -# (e.g. ``Cape Verde Time''), then: -# -# When a country has a single or principal time zone region, -# append `T' to the country's ISO code, e.g. `CVT' for -# Cape Verde Time. For summer time append `ST'; -# for double summer time append `DST'; etc. -# When a country has multiple time zones, take the first three -# letters of an English place name identifying each zone -# and then append `T', `ST', etc. as before; -# e.g. `MOSST' for MOScow Summer Time. -# -# # For Africa I invented the following time zone abbreviations. # LMT Local Mean Time # -1:00 AAT Atlantic Africa Time (no longer used) diff --git a/time/europe b/time/europe index c011424bdc..2948ba1caf 100644 --- a/time/europe +++ b/time/europe @@ -1,4 +1,4 @@ -# @(#)europe 7.45 +# @(#)europe 7.46 # This data is by no means authoritative; if you think you know better, # go ahead and edit the file (and please send any changes to @@ -630,18 +630,18 @@ # came into force on 16 November. It restates the dates from the EC # seventh Summer Time Directive.... # -# From Peter Ilieve (1997-03-28): -# The [European] Transport Council discussed the proposed Eighth Directive -# on 11 March and agreed [to] it, so it moves forward to the next stage, -# from a Commission proposal to a Common Position.... What this means is: -# -# - The eighth directive proposal rules have been accepted. -# These are the same as the current rules (last Sunday in March and last -# Sunday in October). The rules will run until 2001. -# -# - The French have had their request to abandon summer time turned down. -# They have been promised some sort of review in 1999 which might change -# the rules for 2000 and 2001. +# From Peter Ilieve (1997-08-06): +# I now have a copy of the ... Eighth Directive 97/44/EC of the European +# Parliament and of the Council of 22 July 1997 on summer-time arrangements. +# It runs for 4 years, 1998--2001, and confirms the current rules of +# last Sunday in March to last Sunday in October.... +# The directive does not apply in overseas territories of the Member States. +# It says the Commission should produce a proposal for 2002 and beyond +# by 1 Jan 2000 and this should be adopted by 1 Jan 2001. I doubt that +# this will happen though.... +# There is no mention of the French desire to abandon the whole idea. +# France has had a change of government recently so maybe it will +# be quietly dropped. # From Peter Ilieve (1994-03-28): # The [GB-Eire] end date of 22 October [1995] conflicts with your current rule @@ -667,12 +667,12 @@ # Also, for lack of other data, we'll follow Shanks for Eire in 1940-1948. # # Given Peter Ilieve's comments, the following claims by Shanks are incorrect: -# * Wales did not switch from GMT to daylight savings time until +# * Wales did not switch from GMT to daylight saving time until # 1921 Apr 3, when they began to conform with the rest of Great Britain. # Actually, Wales was identical after 1880. # * Eire had two transitions on 1916 Oct 1. # It actually just had one transition. -# * Northern Ireland used single daylight savings time throughout WW II. +# * Northern Ireland used single daylight saving time throughout WW II. # Actually, it conformed to Britain. # * GB-Eire changed standard time to 1 hour ahead of GMT on 1968-02-18. # Actually, that date saw the usual switch to summer time. @@ -681,7 +681,7 @@ # The following claims by Shanks are possible though doubtful; # we'll ignore them for now. # * Jersey, Guernsey, and the Isle of Man did not switch from GMT -# to daylight savings time until 1921 Apr 3, when they began to +# to daylight saving time until 1921 Apr 3, when they began to # conform with Great Britain. # * Dublin's 1971-10-31 switch was at 02:00, even though London's was 03:00. # @@ -1047,7 +1047,7 @@ Zone Europe/Sarajevo 1:13:40 - LMT 1884 1:00 - CET 1941 Apr 18 23:00 1:00 C-Eur CE%sT 1945 May 8 2:00s 1:00 1:00 CEST 1945 Sep 16 2:00s - 1:00 - CET 1982 Oct 11 + 1:00 - CET 1982 Nov 27 1:00 EU CE%sT # Bulgaria @@ -1073,7 +1073,7 @@ Zone Europe/Zagreb 1:03:52 - LMT 1884 1:00 - CET 1941 Apr 18 23:00 1:00 C-Eur CE%sT 1945 May 8 2:00s 1:00 1:00 CEST 1945 Sep 16 2:00s - 1:00 - CET 1982 Oct 11 + 1:00 - CET 1982 Nov 27 1:00 EU CE%sT # Czech Republic @@ -1572,7 +1572,7 @@ Zone Europe/Skopje 1:25:44 - LMT 1884 1:00 - CET 1941 Apr 18 23:00 1:00 C-Eur CE%sT 1945 May 8 2:00s 1:00 1:00 CEST 1945 Sep 16 2:00s - 1:00 - CET 1982 Oct 11 + 1:00 - CET 1982 Nov 27 1:00 EU CE%sT # Malta @@ -1968,7 +1968,7 @@ Zone Europe/Ljubljana 0:58:04 - LMT 1884 1:00 - CET 1941 Apr 18 23:00 1:00 C-Eur CE%sT 1945 May 8 2:00s 1:00 1:00 CEST 1945 Sep 16 2:00s - 1:00 - CET 1982 Oct 11 + 1:00 - CET 1982 Nov 27 1:00 EU CE%sT # Spain @@ -2209,9 +2209,9 @@ Zone Europe/Belgrade 1:22:00 - LMT 1884 1:00 C-Eur CE%sT 1945 May 8 2:00s 1:00 1:00 CEST 1945 Sep 16 2:00s # Metod Kozelj reports that the legal date of -# transition to EU rules was 1982-10-11, for all of Yugoslavia at the time. +# transition to EU rules was 1982-11-27, for all of Yugoslavia at the time. # Shanks doesn't give as much detail, so go with Kozelj. - 1:00 - CET 1982 Oct 11 + 1:00 - CET 1982 Nov 27 1:00 EU CE%sT ############################################################################### diff --git a/time/gmtime.c b/time/gmtime.c index f9627e7b62..2b388befb1 100644 --- a/time/gmtime.c +++ b/time/gmtime.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991, 1993, 1995, 1996, 1997 Free Software Foundation, Inc. +/* Convert `time_t' to `struct tm' in UTC. + Copyright (C) 1991, 1993, 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,19 +17,14 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include /* Defined in localtime.c. */ extern struct tm _tmbuf; -/* Return the `struct tm' representation of *T in UTC. */ -struct tm * -gmtime (t) - const time_t *t; -{ - return __gmtime_r (t, &_tmbuf); -} +/* Prototype for the internal function to get information based on TZ. */ +extern struct tm *__tz_convert __P ((const time_t *t, int use_localtime, + struct tm *tp)); /* Return the `struct tm' representation of *T in UTC, @@ -38,12 +34,15 @@ __gmtime_r (t, tp) const time_t *t; struct tm *tp; { - __offtime (t, 0L, tp); + return __tz_convert (t, 0, tp); +} +weak_alias (__gmtime_r, gmtime_r) - tp->tm_isdst = 0; - tp->tm_gmtoff = 0L; - tp->tm_zone = "GMT"; - return tp; +/* Return the `struct tm' representation of *T in UTC. */ +struct tm * +gmtime (t) + const time_t *t; +{ + return __tz_convert (t, 0, &_tmbuf); } -weak_alias (__gmtime_r, gmtime_r) diff --git a/time/iso3166.tab b/time/iso3166.tab index b5237783c4..6eb4d318db 100644 --- a/time/iso3166.tab +++ b/time/iso3166.tab @@ -7,6 +7,9 @@ # 2. The usual English name for the country, # chosen so that alphabetic sorting of subsets produces helpful lists. # +# For France in Europe, we follow common practice and use FR, +# even though FX might be more technically correct. +# # Columns are separated by a single tab. # The table is sorted by country code. # @@ -86,6 +89,7 @@ FK Falkland Islands FM Micronesia FO Faeroe Islands FR France +FX France, Metropolitan GA Gabon GB Britain (UK) GD Grenada diff --git a/time/localtime.c b/time/localtime.c index ab8fc1ac45..3d8d8fbd10 100644 --- a/time/localtime.c +++ b/time/localtime.c @@ -17,106 +17,33 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include -#include /* The C Standard says that localtime and gmtime return the same pointer. */ struct tm _tmbuf; /* Prototype for the internal function to get information based on TZ. */ -extern void __tzset_internal __P ((int always)); -extern int __tz_compute __P ((time_t timer, struct tm *tp)); -extern int __tzfile_compute __P ((time_t timer, - long int *leap_correct, int *leap_hit)); +extern struct tm *__tz_convert __P ((const time_t *t, int use_localtime, + struct tm *tp)); -extern int __use_tzfile; -/* This lock is defined in tzset.c and locks all the data defined there - and in tzfile.c; the internal functions do no locking themselves. - This lock is only taken here and in `tzset'. */ -__libc_lock_define (extern, __tzset_lock) - - -/* Return the `struct tm' representation of *TIMER in the local timezone. */ -static struct tm * -localtime_internal (const time_t *timer, struct tm *tp) -{ - long int leap_correction; - int leap_extra_secs; - - if (timer == NULL) - { - __set_errno (EINVAL); - return NULL; - } - - if (__use_tzfile) - { - if (! __tzfile_compute (*timer, &leap_correction, &leap_extra_secs)) - tp = NULL; - } - else - { - tp = __gmtime_r (timer, tp); - if (tp && ! __tz_compute (*timer, tp)) - tp = NULL; - leap_correction = 0L; - leap_extra_secs = 0; - } - - if (tp) - { - __offtime (timer, __timezone - leap_correction, tp); - tp->tm_sec += leap_extra_secs; - tp->tm_isdst = __daylight; - tp->tm_gmtoff = __timezone; - tp->tm_zone = __tzname[__daylight]; - } - - return tp; -} - - -/* POSIX.1 8.3.7.2 says that localtime_r is not required to set - tzname. This is a good idea since this allows at least a bit more - parallelism. */ +/* Return the `struct tm' representation of *T in local time, + using *TP to store the result. */ struct tm * -localtime (timer) - const time_t *timer; +__localtime_r (t, tp) + const time_t *t; + struct tm *tp; { - struct tm *result; - - __libc_lock_lock (__tzset_lock); - - /* Update internal database according to current TZ setting. */ - __tzset_internal (1); - - result = localtime_internal (timer, &_tmbuf); - - __libc_lock_unlock (__tzset_lock); - - return result; + return __tz_convert (t, 1, tp); } +weak_alias (__localtime_r, localtime_r) +/* Return the `struct tm' representation of *T in local time. */ struct tm * -__localtime_r (timer, tp) - const time_t *timer; - struct tm *tp; +localtime (t) + const time_t *t; { - struct tm *result; - - __libc_lock_lock (__tzset_lock); - - /* Make sure the database is initialized. */ - __tzset_internal (0); - - result = localtime_internal (timer, tp); - - __libc_lock_unlock (__tzset_lock); - - return result; + return __tz_convert (t, 1, &_tmbuf); } -weak_alias (__localtime_r, localtime_r) diff --git a/time/northamerica b/time/northamerica index b70cb900c0..635c4ef180 100644 --- a/time/northamerica +++ b/time/northamerica @@ -1,4 +1,4 @@ -# @(#)northamerica 7.31 +# @(#)northamerica 7.32 # also includes Central America and the Caribbean # This data is by no means authoritative; if you think you know better, @@ -1249,8 +1249,11 @@ Zone America/Martinique -4:04:20 - LMT 1890 # Fort-de-France -4:00 - AST # Montserrat +# From Paul Eggert (1997-08-31): +# Recent volcanic eruptions have forced evacuation of Plymouth, the capital. +# Luckily, Olveston, the current de facto capital, has the same longitude. # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone America/Montserrat -4:08:52 - LMT 1911 Jul 1 0:01 # Plymouth +Zone America/Montserrat -4:08:52 - LMT 1911 Jul 1 0:01 # Olveston -4:00 - AST # Nicaragua diff --git a/time/southamerica b/time/southamerica index 927f71638a..09e0aa6d28 100644 --- a/time/southamerica +++ b/time/southamerica @@ -1,4 +1,4 @@ -# @(#)southamerica 7.17 +# @(#)southamerica 7.18 # This data is by no means authoritative; if you think you know better, # go ahead and edit the file (and please send any changes to @@ -533,7 +533,9 @@ Rule Uruguay 1989 only - Mar 12 0:00 0 - Rule Uruguay 1989 only - Oct 29 0:00 1:00 S Rule Uruguay 1990 1992 - Mar Sun>=1 0:00 0 - Rule Uruguay 1990 1991 - Oct Sun>=21 0:00 1:00 S -Rule Uruguay 1992 1993 - Oct Sun>=15 0:00 1:00 S +# Shanks's 4th edition (1995) says no DST was observed in 1990/1 and 1991/2, +# and that 1992/3's DST was from 10-25 to 03-01. Go with IATA. +Rule Uruguay 1992 only - Oct 18 0:00 1:00 S Rule Uruguay 1993 only - Feb 28 0:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 diff --git a/time/strftime.c b/time/strftime.c index 891d301f5c..4ecbc5a519 100644 --- a/time/strftime.c +++ b/time/strftime.c @@ -132,7 +132,6 @@ extern char *tzname[]; #ifdef _LIBC # define gmtime_r __gmtime_r # define localtime_r __localtime_r -extern int __tz_compute __P ((time_t timer, const struct tm *tm)); # define tzname __tzname # define tzset __tzset #else diff --git a/time/tzfile.c b/time/tzfile.c index c90e05749f..9289de63a0 100644 --- a/time/tzfile.c +++ b/time/tzfile.c @@ -43,7 +43,7 @@ struct leap long int change; /* Seconds of correction to apply. */ }; -extern const char * __tzstring (const char *); /* Defined in tzset.c. */ +extern char * __tzstring (const char *); /* Defined in tzset.c. */ static struct ttinfo *find_transition (time_t timer); static void compute_tzname_max (size_t); @@ -411,19 +411,23 @@ find_transition (time_t timer) } int -__tzfile_compute (time_t timer, long int *leap_correct, int *leap_hit) +__tzfile_compute (time_t timer, int use_localtime, + long int *leap_correct, int *leap_hit) { - struct ttinfo *info; register size_t i; - info = find_transition (timer); - __daylight = info->isdst; - __timezone = info->offset; - for (i = 0; i < num_types && i < sizeof (__tzname) / sizeof (__tzname[0]); - ++i) - __tzname[types[i].isdst] = &zone_names[types[i].idx]; - if (info->isdst < sizeof (__tzname) / sizeof (__tzname[0])) - __tzname[info->isdst] = &zone_names[info->idx]; + if (use_localtime) + { + struct ttinfo *info = find_transition (timer); + __daylight = info->isdst; + __timezone = info->offset; + for (i = 0; + i < num_types && i < sizeof (__tzname) / sizeof (__tzname[0]); + ++i) + __tzname[types[i].isdst] = &zone_names[types[i].idx]; + if (info->isdst < sizeof (__tzname) / sizeof (__tzname[0])) + __tzname[info->isdst] = &zone_names[info->idx]; + } *leap_correct = 0L; *leap_hit = 0; diff --git a/time/tzset.c b/time/tzset.c index 979a33b069..6ec4e15a86 100644 --- a/time/tzset.c +++ b/time/tzset.c @@ -17,7 +17,8 @@ Boston, MA 02111-1307, USA. */ #include -#include +#include +#include #include #include #include @@ -27,15 +28,19 @@ /* Defined in mktime.c. */ extern const unsigned short int __mon_yday[2][13]; +/* Defined in localtime.c. */ +extern struct tm _tmbuf; + #define NOID #include "tzfile.h" extern int __use_tzfile; extern void __tzfile_read __P ((const char *file)); +extern int __tzfile_compute __P ((time_t timer, int use_localtime, + long int *leap_correct, int *leap_hit)); extern void __tzfile_default __P ((const char *std, const char *dst, long int stdoff, long int dstoff)); -extern const char * __tzstring __P ((const char *string)); -extern int __tz_compute __P ((time_t timer, const struct tm *tm)); +extern char * __tzstring __P ((const char *string)); char *__tzname[2] = { (char *) "GMT", (char *) "GMT" }; int __daylight = 0; @@ -78,6 +83,8 @@ static tz_rule tz_rules[2]; static int compute_change __P ((tz_rule *rule, int year)); +static int tz_compute __P ((time_t timer, const struct tm *tm)); +static void tzset_internal __P ((int always)); /* Header for a list of buffers containing time zone strings. */ struct tzstring_head @@ -102,7 +109,7 @@ static size_t tzstring_last_buffer_size = sizeof tzstring_list.data; /* Allocate a time zone string with given contents. The string will never be moved or deallocated. However, its contents may be shared with other such strings. */ -const char * +char * __tzstring (string) const char *string; { @@ -113,7 +120,7 @@ __tzstring (string) /* Look through time zone string list for a duplicate of this one. */ for (h = &tzstring_list.head; ; h = h->next) { - for (p = (char *) (h + 1); p[0] | p[1]; p++) + for (p = (char *) (h + 1); p[0] | p[1]; ++p) if (strcmp (p, string) == 0) return p; if (! h->next) @@ -122,7 +129,7 @@ __tzstring (string) /* No duplicate was found. Copy to the end of this buffer if there's room; otherwise, append a large-enough new buffer to the list and use it. */ - p++; + ++p; needed = strlen (string) + 2; /* Need 2 trailing '\0's after last string. */ if ((size_t) ((char *) (h + 1) + tzstring_last_buffer_size - p) < needed) @@ -137,16 +144,14 @@ __tzstring (string) p = (char *) (h + 1); } - strncpy (p, string, needed); - return p; + return strncpy (p, string, needed); } static char *old_tz = NULL; /* Interpret the TZ envariable. */ -void __tzset_internal __P ((int always)); -void -__tzset_internal (always) +static void +tzset_internal (always) int always; { static int is_initialized = 0; @@ -338,12 +343,9 @@ __tzset_internal (always) { register tz_rule *tzr = &tz_rules[whichrule]; - if (*tz == ',') - { - ++tz; - if (*tz == '\0') - return; - } + /* Ignore comma to support string following the incorrect + specification in early POSIX.1 printings. */ + tz += *tz == ','; /* Get the date of the change. */ if (*tz == 'J' || isdigit (*tz)) @@ -436,7 +438,7 @@ __tzname_max () { __libc_lock_lock (tzset_lock); - __tzset_internal (0); + tzset_internal (0); __libc_lock_unlock (tzset_lock); @@ -531,13 +533,11 @@ compute_change (rule, year) /* Figure out the correct timezone for *TIMER and TM (which must be the same) and set `__tzname', `__timezone', and `__daylight' accordingly. Return nonzero on success, zero on failure. */ -int -__tz_compute (timer, tm) +static int +tz_compute (timer, tm) time_t timer; const struct tm *tm; { - __tzset_internal (0); - if (! compute_change (&tz_rules[0], 1900 + tm->tm_year) || ! compute_change (&tz_rules[1], 1900 + tm->tm_year)) return 0; @@ -568,7 +568,7 @@ __tzset (void) { __libc_lock_lock (tzset_lock); - __tzset_internal (1); + tzset_internal (1); if (!__use_tzfile) { @@ -580,3 +580,64 @@ __tzset (void) __libc_lock_unlock (tzset_lock); } weak_alias (__tzset, tzset) + +/* Return the `struct tm' representation of *TIMER in the local timezone. + Use local time if USE_LOCALTIME is nonzero, UTC otherwise. */ +struct tm * +__tz_convert (const time_t *timer, int use_localtime, struct tm *tp) +{ + long int leap_correction; + int leap_extra_secs; + + if (timer == NULL) + { + __set_errno (EINVAL); + return NULL; + } + + __libc_lock_lock (tzset_lock); + + /* Update internal database according to current TZ setting. + POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname. + This is a good idea since this allows at least a bit more parallelism. + By analogy we apply the same rule to gmtime_r. */ + tzset_internal (tp == &_tmbuf); + + if (__use_tzfile) + { + if (! __tzfile_compute (*timer, use_localtime, + &leap_correction, &leap_extra_secs)) + tp = NULL; + } + else + { + __offtime (timer, 0, tp); + if (! tz_compute (*timer, tp)) + tp = NULL; + leap_correction = 0L; + leap_extra_secs = 0; + } + + if (tp) + { + if (use_localtime) + { + tp->tm_isdst = __daylight; + tp->tm_zone = __tzname[__daylight]; + tp->tm_gmtoff = __timezone; + } + else + { + tp->tm_isdst = 0; + tp->tm_zone = "GMT"; + tp->tm_gmtoff = 0L; + } + + __offtime (timer, tp->tm_gmtoff - leap_correction, tp); + tp->tm_sec += leap_extra_secs; + } + + __libc_lock_unlock (tzset_lock); + + return tp; +} diff --git a/time/zone.tab b/time/zone.tab index 48b32373cc..df4c157788 100644 --- a/time/zone.tab +++ b/time/zone.tab @@ -231,7 +231,7 @@ MO +2214+11335 Asia/Macao MP +1512+14545 Pacific/Saipan MQ +1436-06105 America/Martinique MR +1806-01557 Africa/Nouakchott -MS +1642-06213 America/Montserrat +MS +1644-06213 America/Montserrat MT +3554+01431 Europe/Malta MU -2010+05730 Indian/Mauritius MV +0410+07330 Indian/Maldives -- cgit 1.4.1