Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: strftime -r (strptime)
- X-seq: zsh-workers 22613
- From: Peter Stephenson <pws@xxxxxxx>
- To: zsh-workers@xxxxxxxxxx (Zsh hackers list)
- Subject: PATCH: strftime -r (strptime)
- Date: Thu, 17 Aug 2006 16:18:49 +0100
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
This makes strftime -r in the zsh/datetime module do a reverse match,
turning a string into an epoch time via strptime(). This small addition
is enough to allow quite powerful functions, which I may get around to
writing.
Index: ChangeLog
===================================================================
RCS file: /cvsroot/zsh/zsh/ChangeLog,v
retrieving revision 1.3227
diff -u -r1.3227 ChangeLog
--- ChangeLog 17 Aug 2006 09:34:11 -0000 1.3227
+++ ChangeLog 17 Aug 2006 15:16:35 -0000
@@ -19,7 +19,7 @@
2006-08-14 Peter Stephenson <pws@xxxxxxx>
- * 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
Index: configure.ac
===================================================================
RCS file: /cvsroot/zsh/zsh/configure.ac,v
retrieving revision 1.56
diff -u -r1.56 configure.ac
--- configure.ac 4 Aug 2006 09:20:25 -0000 1.56
+++ configure.ac 17 Aug 2006 15:16:39 -0000
@@ -1096,7 +1096,8 @@
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 \
Index: Doc/Zsh/mod_datetime.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/mod_datetime.yo,v
retrieving revision 1.2
diff -u -r1.2 mod_datetime.yo
--- Doc/Zsh/mod_datetime.yo 22 Jan 2004 17:51:06 -0000 1.2
+++ Doc/Zsh/mod_datetime.yo 17 Aug 2006 15:16:40 -0000
@@ -6,12 +6,27 @@
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()
Index: Src/Modules/datetime.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/datetime.c,v
retrieving revision 1.14
diff -u -r1.14 datetime.c
--- Src/Modules/datetime.c 30 May 2006 22:35:03 -0000 1.14
+++ Src/Modules/datetime.c 17 Aug 2006 15:16:40 -0000
@@ -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 @@
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 @@
}
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 =
--
Peter Stephenson <pws@xxxxxxx> Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070
To access the latest news from CSR copy this link into a web browser: http://www.csr.com/email_sig.php
Messages sorted by:
Reverse Date,
Date,
Thread,
Author