From 72e44d596f16127f208221d8b455588bd03134e4 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Thu, 22 Jan 2015 19:10:15 +0100
Subject: [PATCH] tag/Format: add %iso8601%

---
 doc/user.xml       |  5 +++++
 src/tag/Format.cxx | 27 +++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/doc/user.xml b/doc/user.xml
index 3fe293ab9..9d95b2864 100644
--- a/doc/user.xml
+++ b/doc/user.xml
@@ -3192,6 +3192,11 @@ buffer_size: 16384</programlisting>
                   <para>
                     An alternative to <varname>path</varname> which
                     provides a format string referring to tag values.
+
+                    The special tag <varname>iso8601</varname> emits
+                    the current date and time in <ulink
+                    url="https://en.wikipedia.org/wiki/ISO_8601">ISO8601</ulink>
+                    format (UTC).
                     Every time a new song starts or a new tag gets
                     received from a radio station, a new file is
                     opened.  If the format does not render a file
diff --git a/src/tag/Format.cxx b/src/tag/Format.cxx
index 3fdcc7db6..de4db57ef 100644
--- a/src/tag/Format.cxx
+++ b/src/tag/Format.cxx
@@ -26,6 +26,7 @@
 #include <algorithm>
 
 #include <string.h>
+#include <time.h>
 
 struct FormatTagContext {
 	const Tag &tag;
@@ -82,6 +83,32 @@ TagGetter(const void *object, const char *name)
 {
 	const auto &_ctx = *(const FormatTagContext *)object;
 	auto &ctx = const_cast<FormatTagContext &>(_ctx);
+
+	if (strcmp(name, "iso8601") == 0) {
+		time_t t = time(nullptr);
+#ifdef WIN32
+		const struct tm *tm2 = gmtime(&t);
+#else
+		struct tm tm;
+		const struct tm *tm2 = gmtime_r(&t, &tm);
+#endif
+		if (tm2 == nullptr)
+			return "";
+
+		strftime(ctx.buffer, sizeof(ctx.buffer),
+#ifdef WIN32
+			 /* kludge: use underscore instead of colon on
+			    Windows because colons are not allowed in
+			    file names, and this library is mostly
+			    used to generate file names */
+			 "%Y-%m-%dT%H_%M_%SZ",
+#else
+			 "%FT%TZ",
+#endif
+			 tm2);
+		return ctx.buffer;
+	}
+
 	const Tag &tag = ctx.tag;
 
 	TagType tag_type = tag_name_parse_i(name);