浏览代码

string(TIMESTAMP): Add %V specifier for ISO 8601 week number

In ISO 8601 weeks begin with Monday. The first week of
the year is the week which contains the first Thursday
of the year.
Antons Jeļkins 4 年之前
父节点
当前提交
aafa392c12

+ 5 - 0
Help/command/string.rst

@@ -493,6 +493,11 @@ specifiers:
 ``%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)
 

+ 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}")