Commit af32fa95 authored by Paul Eggert's avatar Paul Eggert

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.
parent 4c55786d
......@@ -38,14 +38,12 @@ Optional argument DATE is the release date, default today."
emacs-minor-version))
(read-string "Release date: "
(progn (require 'add-log)
(let ((add-log-time-zone-rule t))
(funcall add-log-time-format))))))
(funcall add-log-time-format nil t)))))
(setq root (expand-file-name root))
(unless (file-exists-p (expand-file-name "src/emacs.c" root))
(user-error "%s doesn't seem to be the root of an Emacs source tree" root))
(require 'add-log)
(or date (setq date (let ((add-log-time-zone-rule t))
(funcall add-log-time-format))))
(or date (setq date (funcall add-log-time-format nil t)))
(let* ((logs (process-lines "find" root "-name" "ChangeLog"))
(entry (format "%s %s <%s>\n\n\t* Version %s released.\n\n"
date
......
......@@ -37,20 +37,20 @@ GNULIB_MODULES='
pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat
sig2str socklen stat-time stdalign stddef stdio
stpcpy strftime strtoimax strtoumax symlink sys_stat
sys_time time time_r timer-time timespec-add timespec-sub
sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub
unsetenv update-copyright utimens
vla warnings
'
GNULIB_TOOL_FLAGS='
--avoid=close --avoid=dup
--avoid=fchdir --avoid=fstat
--avoid=fchdir --avoid=flexmember --avoid=fstat
--avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow
--avoid=open --avoid=openat-die --avoid=opendir
--avoid=raise
--avoid=save-cwd --avoid=select --avoid=sigprocmask
--avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask
--avoid=stdarg --avoid=stdbool
--avoid=threadlib
--avoid=threadlib --avoid=unsetenv
--conditional-dependencies --import --no-changelog --no-vc-files
--makefile-name=gnulib.mk
'
......
......@@ -4000,7 +4000,7 @@ AC_SUBST(KRB4LIB)
AC_CHECK_HEADERS(valgrind/valgrind.h)
AC_CHECK_FUNCS_ONCE(tzalloc tzset)
AC_CHECK_FUNCS_ONCE(tzset)
ok_so_far=yes
AC_CHECK_FUNC(socket, , ok_so_far=no)
......
......@@ -1234,7 +1234,7 @@ three-element lists, with omitted @var{microsec} and @var{picosec}
components defaulting to zero.
@cindex time value
Function arguments, e.g., the @var{time-value} argument to
Function arguments, e.g., the @var{time} argument to
@code{current-time-string}, accept a more-general @dfn{time value}
format, which can be a list of integers as above, or a single number
for seconds since the epoch, or @code{nil} for the current time. You
......@@ -1244,7 +1244,7 @@ of integers using @code{seconds-to-time}, and into other forms using
@code{decode-time} and @code{float-time}. These functions are
described in the following sections.
@defun current-time-string &optional time-value
@defun current-time-string &optional time zone
This function returns the current time and date as a human-readable
string. The format does not vary for the initial part of the string,
which contains the day of week, month, day of month, and time of day
......@@ -1255,8 +1255,9 @@ characters from the beginning of the string rather than from the end,
as the year might not have exactly four digits, and additional
information may some day be added at the end.
The argument @var{time-value}, if given, specifies a time to format,
instead of the current time.
The argument @var{time}, if given, specifies a time to format,
instead of the current time. The optional argument @var{zone}
defaults to the current time zone rule.
@example
@group
......@@ -1275,9 +1276,9 @@ multiple of 1000, but this may change as higher-resolution clocks
become available.
@end defun
@defun float-time &optional time-value
@defun float-time &optional time
This function returns the current time as a floating-point number of
seconds since the epoch. The optional argument @var{time-value}, if
seconds since the epoch. The optional argument @var{time}, if
given, specifies a time to convert instead of the current time.
@emph{Warning}: Since the result is floating point, it may not be
......@@ -1286,14 +1287,14 @@ exact. Do not use this function if precise time stamps are required.
@code{time-to-seconds} is an alias for this function.
@end defun
@defun seconds-to-time time-value
@defun seconds-to-time time
This function converts a time value to list-of-integer form.
For example, if @var{time-value} is a number, @code{(time-to-seconds
(seconds-to-time @var{time-value}))} equals the number unless overflow
For example, if @var{time} is a number, @code{(time-to-seconds
(seconds-to-time @var{time}))} equals the number unless overflow
or rounding errors occur.
@end defun
@defun current-time-zone &optional time-value
@defun current-time-zone &optional time zone
@cindex time zone, current
This function returns a list describing the time zone that the user is
in.
......@@ -1309,15 +1310,27 @@ adjustment, then the value is constant through time.
If the operating system doesn't supply all the information necessary to
compute the value, the unknown elements of the list are @code{nil}.
The argument @var{time-value}, if given, specifies a time value to
analyze instead of the current time.
The argument @var{time}, if given, specifies a time value to
analyze instead of the current time. The optional argument @var{zone}
defaults to the current time zone rule.
@end defun
The current time zone is determined by the @env{TZ} environment
@vindex TZ, environment variable
The default time zone is determined by the @env{TZ} environment
variable. @xref{System Environment}. For example, you can tell Emacs
to use universal time with @code{(setenv "TZ" "UTC0")}. If @env{TZ}
is not in the environment, Emacs uses a platform-dependent default
time zone.
to default to universal time with @code{(setenv "TZ" "UTC0")}. If
@env{TZ} is not in the environment, Emacs uses system wall clock time,
which is a platform-dependent default time zone.
@cindex time zone rule
Functions that convert to and from local time accept an optional
@dfn{time zone rule} argument, which specifies the conversion's time
zone and daylight saving time history. If the time zone rule is
omitted or @code{nil}, the conversion uses Emacs's default time zone.
If it is @code{t}, the conversion uses Universal Time. If it is
@code{wall}, the conversion uses the system wall clock time. If it is
a string, the conversion uses the time zone rule equivalent to setting
@env{TZ} to that string.
@node Time Conversion
@section Time Conversion
......@@ -1340,13 +1353,14 @@ count the number of years since the year 1 B.C., and do not skip zero
as traditional Gregorian years do; for example, the year number
@minus{}37 represents the Gregorian year 38 B.C@.
@defun decode-time &optional time-value
@defun decode-time &optional time zone
This function converts a time value into calendrical information. If
you don't specify @var{time-value}, it decodes the current time. The return
you don't specify @var{time}, it decodes the current time, and similarly
@var{zone} defaults to the current time zone rule. The return
value is a list of nine elements, as follows:
@example
(@var{seconds} @var{minutes} @var{hour} @var{day} @var{month} @var{year} @var{dow} @var{dst} @var{zone})
(@var{seconds} @var{minutes} @var{hour} @var{day} @var{month} @var{year} @var{dow} @var{dst} @var{utcoff})
@end example
Here is what the elements mean:
......@@ -1370,13 +1384,13 @@ The day of week, as an integer between 0 and 6, where 0 stands for
Sunday.
@item dst
@code{t} if daylight saving time is effect, otherwise @code{nil}.
@item zone
An integer indicating the time zone, as the number of seconds east of
Greenwich.
@item utcoff
An integer indicating the UTC offset in seconds, i.e., the number of
seconds east of Greenwich.
@end table
@strong{Common Lisp Note:} Common Lisp has different meanings for
@var{dow} and @var{zone}.
@var{dow} and @var{utcoff}.
@end defun
@defun encode-time seconds minutes hour day month year &optional zone
......@@ -1389,12 +1403,11 @@ Year numbers less than 100 are not treated specially. If you want them
to stand for years above 1900, or years above 2000, you must alter them
yourself before you call @code{encode-time}.
The optional argument @var{zone} defaults to the current time zone and
its daylight saving time rules. If specified, it can be either a list
(as you would get from @code{current-time-zone}), a string as in the
@env{TZ} environment variable, @code{t} for Universal Time, or an
integer (as you would get from @code{decode-time}). The specified
zone is used without any further alteration for daylight saving time.
The optional argument @var{zone} defaults to the current time zone rule.
In addition to the usual time zone rule values, it can also be a list
(as you would get from @code{current-time-zone}) or an integer (as
from @code{decode-time}), applied without any further alteration for
daylight saving time.
If you pass more than seven arguments to @code{encode-time}, the first
six are used as @var{seconds} through @var{year}, the last argument is
......@@ -1430,11 +1443,12 @@ This function parses the time-string @var{string} and returns the
corresponding time value.
@end defun
@defun format-time-string format-string &optional time-value universal
@defun format-time-string format-string &optional time zone
This function converts @var{time-value} (or the current time, if
@var{time-value} is omitted) to a string according to
@var{format-string}. The argument
This function converts @var{time} (or the current time, if
@var{time} is omitted) to a string according to
@var{format-string}. The conversion uses the time zone rule @var{zone}
(or the current time zone rule, if omitted). The argument
@var{format-string} may contain @samp{%}-sequences which say to
substitute parts of the time. Here is a table of what the
@samp{%}-sequences mean:
......
......@@ -1014,6 +1014,15 @@ key works) by typing ‘A-[’ and ‘A-]’.
+++
** Time-related changes:
*** Time conversion functions now accept an optional ZONE argument
that specifies the time zone rules for conversion. ZONE is omitted or
nil for Emacs local time, t for Universal Time, wall for system wall
clock time, or a string as in set-time-zone-rule for a time zone
rule. The affected functions are current-time-string,
current-time-zone, decode-time, and format-time-string. The
function encode-time, which already accepted a simple time zone rule
argument, has been extended to accept all the new forms.
*** Time-related functions now consistently accept numbers
(representing seconds since the epoch) and nil (representing the
current time) as well as the usual list-of-integer representation.
......
......@@ -21,7 +21,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=stdarg --avoid=stdbool --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time stdalign stddef stdio stpcpy strftime strtoimax strtoumax symlink sys_stat sys_time time time_r timer-time timespec-add timespec-sub unsetenv update-copyright utimens vla warnings
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=flexmember --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=unsetenv --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time stdalign stddef stdio stpcpy strftime strtoimax strtoumax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub unsetenv update-copyright utimens vla warnings
MOSTLYCLEANFILES += core *.stackdump
......@@ -655,6 +655,17 @@ EXTRA_libgnu_a_SOURCES += mktime.c
## end gnulib module mktime
## begin gnulib module mktime-internal
if gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31
endif
EXTRA_DIST += mktime-internal.h mktime.c
EXTRA_libgnu_a_SOURCES += mktime.c
## end gnulib module mktime-internal
## begin gnulib module openat-h
if gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7
......@@ -1589,10 +1600,12 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \
-e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \
-e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \
-e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \
-e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \
-e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \
-e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
-e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|g' \
-e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \
-e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \
-e 's|@''REPLACE_LOCALTIME''@|$(REPLACE_LOCALTIME)|g' \
-e 's|@''REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|g' \
......@@ -1624,6 +1637,24 @@ EXTRA_libgnu_a_SOURCES += time_r.c
## end gnulib module time_r
## begin gnulib module time_rz
EXTRA_DIST += time_rz.c
EXTRA_libgnu_a_SOURCES += time_rz.c
## end gnulib module time_rz
## begin gnulib module timegm
EXTRA_DIST += mktime-internal.h timegm.c
EXTRA_libgnu_a_SOURCES += timegm.c
## end gnulib module timegm
## begin gnulib module timespec
libgnu_a_SOURCES += timespec.c
......@@ -1806,15 +1837,6 @@ EXTRA_DIST += unistd.in.h
## end gnulib module unistd
## begin gnulib module unsetenv
EXTRA_DIST += unsetenv.c
EXTRA_libgnu_a_SOURCES += unsetenv.c
## end gnulib module unsetenv
## begin gnulib module update-copyright
......
......@@ -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
......@@ -23,11 +23,10 @@ extern "C" {
/* Just like strftime, but with two more arguments:
POSIX requires that strftime use the local timezone information.
When __UTC is nonzero and tm->tm_zone is NULL or the empty string,
use UTC instead. Use __NS as the number of nanoseconds in the
%N directive. */
Use the timezone __TZ instead. Use __NS as the number of
nanoseconds in the %N directive. */
size_t nstrftime (char *, size_t, char const *, struct tm const *,
int __utc, int __ns);
timezone_t __tz, int __ns);
#ifdef __cplusplus
}
......
......@@ -231,6 +231,25 @@ _GL_CXXALIAS_SYS (strptime, char *, (char const *restrict __buf,
_GL_CXXALIASWARN (strptime);
# endif
# if defined _GNU_SOURCE && @GNULIB_TIME_RZ@ && ! @HAVE_TIMEZONE_T@
typedef struct tm_zone *timezone_t;
_GL_FUNCDECL_SYS (tzalloc, timezone_t, (char const *__name));
_GL_CXXALIAS_SYS (tzalloc, timezone_t, (char const *__name));
_GL_FUNCDECL_SYS (tzfree, void, (timezone_t __tz));
_GL_CXXALIAS_SYS (tzfree, void, (timezone_t __tz));
_GL_FUNCDECL_SYS (localtime_rz, struct tm *,
(timezone_t __tz, time_t const *restrict __timer,
struct tm *restrict __result) _GL_ARG_NONNULL ((2, 3)));
_GL_CXXALIAS_SYS (localtime_rz, struct tm *,
(timezone_t __tz, time_t const *restrict __timer,
struct tm *restrict __result));
_GL_FUNCDECL_SYS (mktime_z, time_t,
(timezone_t __tz, struct tm *restrict __result)
_GL_ARG_NONNULL ((2)));
_GL_CXXALIAS_SYS (mktime_z, time_t,
(timezone_t __tz, struct tm *restrict __result));
# endif
/* Convert TM to a time_t value, assuming UTC. */
# if @GNULIB_TIMEGM@
# if @REPLACE_TIMEGM@
......
This diff is collapsed.
/* Convert UTC calendar time to simple time. Like mktime but assumes UTC.
Copyright (C) 1994, 1997, 2003-2004, 2006-2007, 2009-2015 Free Software
Foundation, Inc. This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. */
#ifndef _LIBC
# include <config.h>
#endif
#include <time.h>
#ifndef _LIBC
# undef __gmtime_r
# define __gmtime_r gmtime_r
# define __mktime_internal mktime_internal
# include "mktime-internal.h"
#endif
time_t
timegm (struct tm *tmp)
{
static time_t gmtime_offset;
tmp->tm_isdst = 0;
return __mktime_internal (tmp, __gmtime_r, &gmtime_offset);
}
......@@ -420,16 +420,8 @@ format the string."
(or ts-format
(setq ts-format time-stamp-format))
(if (stringp ts-format)
(if (stringp time-stamp-time-zone)
(let ((ts-real-time-zone (getenv "TZ")))
(unwind-protect
(progn
(setenv "TZ" time-stamp-time-zone)
(format-time-string
(time-stamp-string-preprocess ts-format)))
(setenv "TZ" ts-real-time-zone)))
(format-time-string
(time-stamp-string-preprocess ts-format)))
(format-time-string (time-stamp-string-preprocess ts-format)
nil time-stamp-time-zone)
;; handle version 1 compatibility
(cond ((or (eq time-stamp-old-format-warn 'error)
(and (eq time-stamp-old-format-warn 'ask)
......
......@@ -160,15 +160,8 @@ LABEL is a string to display as the label of that TIMEZONE's time."
(defcustom display-time-world-list
;; Determine if zoneinfo style timezones are supported by testing that
;; America/New York and Europe/London return different timezones.
(let ((old-tz (getenv "TZ"))
gmt nyt)
(unwind-protect
(progn
(setenv "TZ" "America/New_York")
(setq nyt (format-time-string "%z"))
(setenv "TZ" "Europe/London")
(setq gmt (format-time-string "%z")))
(setenv "TZ" old-tz))
(let ((nyt (format-time-string "%z" nil "America/New_York"))
(gmt (format-time-string "%z" nil "Europe/London")))
(if (string-equal nyt gmt)
legacy-style-world-list
zoneinfo-style-world-list))
......@@ -523,21 +516,19 @@ See `display-time-world'."
"Replace current buffer text with times in various zones, based on ALIST."
(let ((inhibit-read-only t)
(buffer-undo-list t)
(old-tz (getenv "TZ"))
(now (current-time))
(max-width 0)
result fmt)
(erase-buffer)
(unwind-protect
(dolist (zone alist)
(let* ((label (cadr zone))
(width (string-width label)))
(setenv "TZ" (car zone))
(push (cons label
(format-time-string display-time-world-time-format))
result)
(when (> width max-width)
(setq max-width width))))
(setenv "TZ" old-tz))
(dolist (zone alist)
(let* ((label (cadr zone))
(width (string-width label)))
(push (cons label
(format-time-string display-time-world-time-format
now (car zone)))
result)
(when (> width max-width)
(setq max-width width))))
(setq fmt (concat "%-" (int-to-string max-width) "s %s\n"))
(dolist (timedata (nreverse result))
(insert (format fmt (car timedata) (cdr timedata))))
......
......@@ -581,8 +581,8 @@ If t, use universal time.")
(put 'add-log-time-zone-rule 'safe-local-variable
(lambda (x) (or (booleanp x) (stringp x))))
(defun add-log-iso8601-time-zone (&optional time)
(let* ((utc-offset (or (car (current-time-zone time)) 0))
(defun add-log-iso8601-time-zone (&optional time zone)
(let* ((utc-offset (or (car (current-time-zone time zone)) 0))
(sign (if (< utc-offset 0) ?- ?+))
(sec (abs utc-offset))
(ss (% sec 60))
......@@ -596,12 +596,11 @@ If t, use universal time.")
(defvar add-log-iso8601-with-time-zone nil)
(defun add-log-iso8601-time-string ()
(let ((time (format-time-string "%Y-%m-%d"
nil (eq t add-log-time-zone-rule))))
(defun add-log-iso8601-time-string (&optional time zone)
(let ((date (format-time-string "%Y-%m-%d" time zone)))
(if add-log-iso8601-with-time-zone
(concat time " " (add-log-iso8601-time-zone))
time)))
(concat date " " (add-log-iso8601-time-zone time zone))
date)))
(defun change-log-name ()
"Return (system-dependent) default name for a change log file."
......@@ -848,14 +847,8 @@ non-nil, otherwise in local time."
(let ((new-entries
(mapcar (lambda (addr)
(concat
(if (stringp add-log-time-zone-rule)
(let ((tz (getenv "TZ")))
(unwind-protect
(progn
(setenv "TZ" add-log-time-zone-rule)