summaryrefslogtreecommitdiff
path: root/lib/strftime.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2015-07-26 00:01:34 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2015-07-26 12:44:54 -0700
commitaf32fa956267af40db61051c248597144d41521c (patch)
treeafd650b9f9805474df149081e51cc8abae3bdb87 /lib/strftime.c
parent4c55786d9b2a5d571f3e543cc261ce0702c7341e (diff)
downloademacs-af32fa956267af40db61051c248597144d41521c.tar.gz
New optional ZONE arg for format-time-string etc.
This simplifies time conversions in other time zones. It also prevents display-time-world tampering with TZ (Bug#21020). * admin/admin.el (add-release-logs): Use improved add-log-time-format API. * admin/merge-gnulib (GNULIB_MODULES): Add time_rz, timegm. (GNULIB_TOOL_FLAGS): Avoid flexmember, setenv, unsetenv. * configure.ac (tzalloc): Remove test for this, since Emacs no longer uses HAVE_TZALLOC directly. * doc/lispref/os.texi (Time of Day, Time Conversion) (Time Parsing): * etc/NEWS: Document the new behavior. Merge from gnulib, incorporating: 2015-07-25 strftime: fix newly-introduced bug on Solaris 2015-07-23 fprintftime, strftime: use timezone_t args * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * lib/strftime.c, lib/strftime.h, lib/time.in.h, m4/sys_time_h.m4: * m4/time_h.m4: Update from gnulib. * lib/time_rz.c, lib/timegm.c, m4/time_rz.m4, m4/timegm.m4: New files from gnulib. * lisp/time-stamp.el (time-stamp-string): * lisp/time.el (display-time-world-list) (display-time-world-display): Use new API, with time zone arg. * lisp/time.el (display-time-world-display): Fix race when current-time advances while we're running. * lisp/vc/add-log.el (add-log-iso8601-time-zone) (add-log-iso8601-time-string): Accept optional time zone arg. * lisp/vc/add-log.el (add-change-log-entry): * lisp/vc/log-edit.el (log-edit-changelog-ours-p): Use new arg. * nt/gnulib.mk: Propagate lib/gnulib.mk changes here. Add rules for the time module, since they're now needed for tzalloc etc. * src/conf_post.h (getenv_TZ, setenv_TZ): New macros. (emacs_getenv_TZ, emacs_setenv_TZ): New decls. * src/editfns.c: Include errno.h. (set_time_zone_rule): Omit unnecessary forward decl. (initial_tz): Remove, replacing with ... (local_tz, wall_clock_tz, utc_tz): New static vars and constants. (tzeqlen): New constant; prefer it to (sizeof "TZ=" - 1). (emacs_localtime_rz, emacs_mktime_z, xtzalloc, xtzfree) (tzlookup): New static functions. (init_editfns): New arg DUMPING. All uses changed. (init_editfns): Omit most initialization if dumping, not if !initialized. Initialize wall_clock_tz and local_tz. (emacs_nmemftime, format_time_string): Time zone argument can now be any time zone, not just a boolean for UTC or local time. All callers changed. (Fformat_time_string, Fencode_time, Fcurrent_time_string) (Fcurrent_time_zone): New optional arg ZONE. (Fdecode_time, Fset_time_zone_rule): ZONE arg can now also take the same form as with the other new additions. (decode_time_zone): Remove; no longer needed. (tzvalbuf): Now file-scope. (emacs_getenv_TZ, emacs_setenv_TZ): New functions. (syms_of_editfns): Define Qwall. * src/editfns.c (mktime_z) [!HAVE_TZALLOC]: * src/systime.h (mktime_z, timezone_t, tzalloc, tzfree) [!HAVE_TZALLOC]: Remove; now supplied by gnulib. * src/emacs.c (main): * src/lisp.h (init_editfns): Adjust to init_editfns API change.
Diffstat (limited to 'lib/strftime.c')
-rw-r--r--lib/strftime.c64
1 files changed, 17 insertions, 47 deletions
diff --git a/lib/strftime.c b/lib/strftime.c
index 2426aae7052..c7cec2621c9 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -121,22 +121,11 @@ extern char *tzname[];
#ifdef _LIBC
+# define mktime_z(tz, tm) mktime (tm)
# define tzname __tzname
# define tzset __tzset
#endif
-#if !HAVE_TM_GMTOFF
-/* Portable standalone applications should supply a "time.h" that
- declares a POSIX-compliant localtime_r, for the benefit of older
- implementations that lack localtime_r or have a nonstandard one.
- See the gnulib time_r module for one way to implement this. */
-# undef __gmtime_r
-# undef __localtime_r
-# define __gmtime_r gmtime_r
-# define __localtime_r localtime_r
-#endif
-
-
#ifndef FPRINTFTIME
# define FPRINTFTIME 0
#endif
@@ -385,12 +374,7 @@ iso_week_days (int yday, int wday)
/* When compiling this file, GNU applications can #define my_strftime
to a symbol (typically nstrftime) to get an extended strftime with
- extra arguments UT and NS. Emacs is a special case for now, but
- this Emacs-specific code can be removed once Emacs's config.h
- defines my_strftime. */
-#if defined emacs && !defined my_strftime
-# define my_strftime nstrftime
-#endif
+ extra arguments TZ and NS. */
#if FPRINTFTIME
# undef my_strftime
@@ -398,8 +382,9 @@ iso_week_days (int yday, int wday)
#endif
#ifdef my_strftime
-# define extra_args , ut, ns
-# define extra_args_spec , int ut, int ns
+# undef HAVE_TZSET
+# define extra_args , tz, ns
+# define extra_args_spec , timezone_t tz, int ns
#else
# if defined COMPILE_WIDE
# define my_strftime wcsftime
@@ -411,7 +396,7 @@ iso_week_days (int yday, int wday)
# define extra_args
# define extra_args_spec
/* We don't have this information in general. */
-# define ut 0
+# define tz 1
# define ns 0
#endif
@@ -483,7 +468,7 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
zone = (const char *) tp->tm_zone;
#endif
#if HAVE_TZNAME
- if (ut)
+ if (!tz)
{
if (! (zone && *zone))
zone = "GMT";
@@ -496,7 +481,12 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
tzset ();
# endif
}
+ /* The tzset() call might have changed the value. */
+ if (!(zone && *zone) && tp->tm_isdst >= 0)
+ zone = tzname[tp->tm_isdst != 0];
#endif
+ if (! zone)
+ zone = "";
if (hour12 > 12)
hour12 -= 12;
@@ -1144,7 +1134,7 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
time_t t;
ltm = *tp;
- t = mktime (&ltm);
+ t = mktime_z (tz, &ltm);
/* Generate string value for T using time_t arithmetic;
this works even if sizeof (long) < sizeof (time_t). */
@@ -1319,14 +1309,6 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
to_lowcase = true;
}
-#if HAVE_TZNAME
- /* The tzset() call might have changed the value. */
- if (!(zone && *zone) && tp->tm_isdst >= 0)
- zone = tzname[tp->tm_isdst != 0];
-#endif
- if (! zone)
- zone = "";
-
#ifdef COMPILE_WIDE
{
/* The zone string is always given in multibyte form. We have
@@ -1366,7 +1348,7 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
#if HAVE_TM_GMTOFF
diff = tp->tm_gmtoff;
#else
- if (ut)
+ if (!tz)
diff = 0;
else
{
@@ -1375,7 +1357,7 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
time_t lt;
ltm = *tp;
- lt = mktime (&ltm);
+ lt = mktime_z (tz, &ltm);
if (lt == (time_t) -1)
{
@@ -1384,7 +1366,7 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
occurred. */
struct tm tm;
- if (! __localtime_r (&lt, &tm)
+ if (! localtime_rz (tz, &lt, &tm)
|| ((ltm.tm_sec ^ tm.tm_sec)
| (ltm.tm_min ^ tm.tm_min)
| (ltm.tm_hour ^ tm.tm_hour)
@@ -1394,7 +1376,7 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
break;
}
- if (! __gmtime_r (&lt, &gtm))
+ if (! localtime_rz (0, &lt, &gtm))
break;
diff = tm_diff (&ltm, &gtm);
@@ -1473,15 +1455,3 @@ my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
#if defined _LIBC && ! FPRINTFTIME
libc_hidden_def (my_strftime)
#endif
-
-
-#if defined emacs && ! FPRINTFTIME
-/* For Emacs we have a separate interface which corresponds to the normal
- strftime function plus the ut argument, but without the ns argument. */
-size_t
-emacs_strftimeu (char *s, size_t maxsize, const char *format,
- const struct tm *tp, int ut)
-{
- return my_strftime (s, maxsize, format, tp, ut, 0);
-}
-#endif