mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-23 17:01:05 +02:00
22613: add strftime -r to use strptime() if available
This commit is contained in:
parent
1a42aadd81
commit
d0b9eddd9a
4 changed files with 90 additions and 6 deletions
|
@ -1,5 +1,9 @@
|
|||
2006-08-17 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 22613: configure.ac, Doc/Zsh/mod_datetime.yo,
|
||||
Src/Modules/datetime.c: add strftime -r to use strptime()
|
||||
if available.
|
||||
|
||||
* 22612: Src/Zle/complist.c: comment the static variables.
|
||||
|
||||
2006-08-16 Peter Stephenson <pws@csr.com>
|
||||
|
@ -19,7 +23,7 @@
|
|||
|
||||
2006-08-14 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 22608: Doc/Zsh/contrib.yo: improvments on 22606.
|
||||
* 22608: Doc/Zsh/contrib.yo: improvements on 22606.
|
||||
|
||||
* 22606: Doc/Zsh/contrib.yo, Functions/Zle/match-word-context,
|
||||
Functions/Zle/match-words-by-style, Functions/Zle/.distfiles: new
|
||||
|
|
|
@ -6,12 +6,27 @@ The tt(zsh/datetime) module makes available one builtin command:
|
|||
startitem()
|
||||
findex(strftime)
|
||||
cindex(date string, printing)
|
||||
item(tt(strftime) [ tt(-s) var(scalar) ] var(format) var(epochtime) )(
|
||||
xitem(tt(strftime) [ tt(-s) var(scalar) ] var(format) var(epochtime) )
|
||||
item(tt(strftime) tt(-r) [ tt(-q) ] [ tt(-s) var(scalar) ] var(format) var(timestring) )(
|
||||
Output the date denoted by var(epochtime) in the var(format)
|
||||
specified.
|
||||
|
||||
If tt(-s) var(scalar) is given, assign the date to var(scalar) instead
|
||||
of printing it.
|
||||
With the option tt(-r) (reverse), use the format var(format) to parse the
|
||||
input string var(timestring) and output the number of seconds since the
|
||||
epoch at which the time occurred. If no timezone is parsed, the current
|
||||
timezone is used; other parameters are set to zero if not present. If
|
||||
var(timestring) does not match var(format) the command returns status 1; it
|
||||
will additionally print an error message unless the option tt(-q) (quiet)
|
||||
is given. If var(timestring) matches var(format) but not all characters in
|
||||
var(timestring) were used, the conversion succeeds; however, a warning is
|
||||
issued unless the option tt(-q) is given. The matching is implemented by
|
||||
the system function tt(strptime); see manref(strptime)(3). This means that
|
||||
zsh format extensions are not available, however for reverse lookup they
|
||||
are not required. If the function is not implemented, the command returns
|
||||
status 2 and (unless tt(-q) is given) prints a message.
|
||||
|
||||
If tt(-s) var(scalar) is given, assign the date string (or epoch time
|
||||
in seconds if tt(-r) is given) to var(scalar) instead of printing it.
|
||||
)
|
||||
enditem()
|
||||
|
||||
|
|
|
@ -31,6 +31,68 @@
|
|||
#include "datetime.pro"
|
||||
#include <time.h>
|
||||
|
||||
#ifndef HAVE_MKTIME
|
||||
#ifdef HAVE_TIMELOCAL
|
||||
#define mktime(x) timelocal(x)
|
||||
#define HAVE_MKTIME 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int
|
||||
reverse_strftime(char *nam, char **argv, char *scalar, int quiet)
|
||||
{
|
||||
#if defined(HAVE_STRPTIME) && defined(HAVE_MKTIME)
|
||||
struct tm tm;
|
||||
zlong mytime;
|
||||
char *endp;
|
||||
|
||||
/*
|
||||
* Initialise all parameters to zero; there's no floating point
|
||||
* so memset() will do the trick. The exception is that tm_isdst
|
||||
* is set to -1 which, if not overridden, will cause mktime()
|
||||
* to use the current timezone. This is probably the best guess;
|
||||
* it's the one that will cause dates and times output by strftime
|
||||
* without the -r option and without an explicit timezone to be
|
||||
* converted back correctly.
|
||||
*/
|
||||
(void)memset(&tm, 0, sizeof(tm));
|
||||
tm.tm_isdst = -1;
|
||||
endp = strptime(argv[1], argv[0], &tm);
|
||||
|
||||
if (!endp) {
|
||||
/* Conversion failed completely. */
|
||||
if (!quiet)
|
||||
zwarnnam(nam, "format not matched");
|
||||
return 1;
|
||||
}
|
||||
|
||||
mytime = (zlong)mktime(&tm);
|
||||
|
||||
if (scalar)
|
||||
setiparam(scalar, mytime);
|
||||
else {
|
||||
char buf[DIGBUFSIZE];
|
||||
convbase(buf, mytime, 10);
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
|
||||
if (*endp && !quiet) {
|
||||
/*
|
||||
* Not everything in the input string was converted.
|
||||
* This is probably benign, since the format has been satisfied,
|
||||
* but issue a warning unless the quiet flag is set.
|
||||
*/
|
||||
zwarnnam(nam, "warning: input string not completely matched");
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
if (!quiet)
|
||||
zwarnnam(nam, "not implemented on this system");
|
||||
return 2;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
bin_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
|
||||
{
|
||||
|
@ -46,6 +108,8 @@ bin_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
if (OPT_ISSET(ops, 'r'))
|
||||
return reverse_strftime(nam, argv, scalar, OPT_ISSET(ops, 'q'));
|
||||
|
||||
secs = (time_t)strtoul(argv[1], &endptr, 10);
|
||||
if (secs == (time_t)ULONG_MAX) {
|
||||
|
@ -83,7 +147,7 @@ getcurrentsecs()
|
|||
}
|
||||
|
||||
static struct builtin bintab[] = {
|
||||
BUILTIN("strftime", 0, bin_strftime, 2, 2, 0, "s:", NULL),
|
||||
BUILTIN("strftime", 0, bin_strftime, 2, 2, 0, "qrs:", NULL),
|
||||
};
|
||||
|
||||
static const struct gsu_integer epochseconds_gsu =
|
||||
|
|
|
@ -1096,7 +1096,8 @@ dnl ---------------
|
|||
dnl need to integrate this function
|
||||
dnl AC_FUNC_STRFTIME
|
||||
|
||||
AC_CHECK_FUNCS(strftime difftime gettimeofday \
|
||||
AC_CHECK_FUNCS(strftime strptime mktime timelocal \
|
||||
difftime gettimeofday \
|
||||
select poll \
|
||||
readlink faccessx fchdir ftruncate \
|
||||
fstat lstat lchown fchown fchmod \
|
||||
|
|
Loading…
Reference in a new issue