Browse Source

Merge topic 'string-TIMESTAMP-specifier-V'

aafa392c12 string(TIMESTAMP): Add %V specifier for ISO 8601 week number
a915f691ad Help: Format string(TIMESTAMP) format specifiers as a definition list

Acked-by: Kitware Robot <[email protected]>
Merge-request: !6374
Brad King 4 years ago
parent
commit
70daea512d

+ 63 - 28
Help/command/string.rst

@@ -449,38 +449,73 @@ be in Coordinated Universal Time (UTC) rather than local time.
 The optional ``<format_string>`` may contain the following format
 specifiers:
 
-::
+``%%``
+  .. versionadded:: 3.8
 
-   %%        A literal percent sign (%).
-   %d        The day of the current month (01-31).
-   %H        The hour on a 24-hour clock (00-23).
-   %I        The hour on a 12-hour clock (01-12).
-   %j        The day of the current year (001-366).
-   %m        The month of the current year (01-12).
-   %b        Abbreviated month name (e.g. Oct).
-   %B        Full month name (e.g. October).
-   %M        The minute of the current hour (00-59).
-   %s        Seconds since midnight (UTC) 1-Jan-1970 (UNIX time).
-   %S        The second of the current minute.
-             60 represents a leap second. (00-60)
-   %U        The week number of the current year (00-53).
-   %w        The day of the current week. 0 is Sunday. (0-6)
-   %a        Abbreviated weekday name (e.g. Fri).
-   %A        Full weekday name (e.g. Friday).
-   %y        The last two digits of the current year (00-99)
-   %Y        The current year.
-
-.. versionadded:: 3.6
-  ``%s`` format specifier (UNIX time).
+  A literal percent sign (%).
 
-.. versionadded:: 3.7
-  ``%a`` and ``%b`` format specifiers (abbreviated month and weekday names).
+``%d``
+  The day of the current month (01-31).
 
-.. versionadded:: 3.8
-  ``%%`` specifier (literal ``%``).
+``%H``
+  The hour on a 24-hour clock (00-23).
 
-.. versionadded:: 3.7
-  ``%A`` and ``%B`` format specifiers (full month and weekday names).
+``%I``
+  The hour on a 12-hour clock (01-12).
+
+``%j``
+  The day of the current year (001-366).
+
+``%m``
+  The month of the current year (01-12).
+
+``%b``
+  .. versionadded:: 3.7
+
+  Abbreviated month name (e.g. Oct).
+
+``%B``
+  .. versionadded:: 3.10
+
+  Full month name (e.g. October).
+
+``%M``
+  The minute of the current hour (00-59).
+
+``%s``
+  .. versionadded:: 3.6
+
+  Seconds since midnight (UTC) 1-Jan-1970 (UNIX time).
+
+``%S``
+  The second of the current minute.  60 represents a leap second. (00-60)
+
+``%U``
+  The week number of the current year (00-53).
+
+``%V``
+  .. versionadded:: 3.22
+
+  The ISO 8601 week number of the current year (01-53).
+
+``%w``
+  The day of the current week. 0 is Sunday. (0-6)
+
+``%a``
+  .. versionadded:: 3.7
+
+  Abbreviated weekday name (e.g. Fri).
+
+``%A``
+  .. versionadded:: 3.10
+
+  Full weekday name (e.g. Friday).
+
+``%y``
+  The last two digits of the current year (00-99).
+
+``%Y``
+  The current year.
 
 Unknown format specifiers will be ignored and copied to the output
 as-is.

+ 5 - 0
Help/release/dev/string-TIMESTAMP-specifier-V.rst

@@ -0,0 +1,5 @@
+string-TIMESTAMP-specifier-V
+----------------------------
+
+* The :command:`string(TIMESTAMP)` command now supports the ``%V``
+  specifier for ISO 8601 week numbers.

+ 23 - 0
Source/cmTimestamp.cxx

@@ -18,6 +18,10 @@
 #include <cstring>
 #include <sstream>
 
+#ifdef __MINGW32__
+#  include <libloaderapi.h>
+#endif
+
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
@@ -159,6 +163,7 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
     case 'M':
     case 'S':
     case 'U':
+    case 'V':
     case 'w':
     case 'y':
     case 'Y':
@@ -187,6 +192,24 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
     }
   }
 
+#ifdef __MINGW32__
+  /* See a bug in MinGW: https://sourceforge.net/p/mingw-w64/bugs/793/. A work
+   * around is to try to use strftime() from ucrtbase.dll. */
+  using T = size_t(WINAPI*)(char*, size_t, const char*, const struct tm*);
+  auto loadStrftime = [] {
+    auto handle =
+      LoadLibraryExA("ucrtbase.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
+    if (handle) {
+#  pragma GCC diagnostic push
+#  pragma GCC diagnostic ignored "-Wcast-function-type"
+      return reinterpret_cast<T>(GetProcAddress(handle, "strftime"));
+#  pragma GCC diagnostic pop
+    }
+    return strftime;
+  };
+  static T strftime = loadStrftime();
+#endif
+
   char buffer[16];
 
   size_t size =

+ 1 - 1
Tests/RunCMake/string/Timestamp-stderr.txt

@@ -1 +1 @@
-RESULT=2005-08-07 23:19:49 Sunday=Sun August=Aug 05 day=219 wd=0 week=32 %I=11 epoch=1123456789
+RESULT=2005-08-07 23:19:49 Sunday=Sun August=Aug 05 day=219 wd=0 week=32 w_iso=31 %I=11 epoch=1123456789

+ 1 - 1
Tests/RunCMake/string/Timestamp.cmake

@@ -1,3 +1,3 @@
 set(ENV{SOURCE_DATE_EPOCH} "1123456789")
-string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S %A=%a %B=%b %y day=%j wd=%w week=%U %%I=%I epoch=%s" UTC)
+string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s" UTC)
 message("RESULT=${RESULT}")