mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-30 10:20:56 -06:00
string(TIMESTAMP): Add %z and %Z for adding time zone string
Fixes: #24056
This commit is contained in:
committed by
Brad King
parent
2954a810ce
commit
9da542d5c1
@@ -522,6 +522,17 @@ specifiers:
|
||||
``%Y``
|
||||
The current year.
|
||||
|
||||
``%z``
|
||||
.. versionadded:: 3.26
|
||||
|
||||
The offset of the time zone from UTC, in hours and minutes,
|
||||
with format ``+hhmm`` or ``-hhmm``.
|
||||
|
||||
``%Z``
|
||||
.. versionadded:: 3.26
|
||||
|
||||
The time zone name.
|
||||
|
||||
Unknown format specifiers will be ignored and copied to the output
|
||||
as-is.
|
||||
|
||||
|
||||
5
Help/release/dev/timestamp-timezone.rst
Normal file
5
Help/release/dev/timestamp-timezone.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
timestamp-timezone
|
||||
------------------
|
||||
|
||||
* The :command:`string(TIMESTAMP)` and :command:`file(TIMESTAMP)` commands
|
||||
now support the ``%z`` and ``%Z`` specifiers for the time zone.
|
||||
@@ -128,8 +128,8 @@ std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
|
||||
: static_cast<char>(0);
|
||||
|
||||
if (c1 == '%' && c2 != 0) {
|
||||
result +=
|
||||
this->AddTimestampComponent(c2, timeStruct, timeT, microseconds);
|
||||
result += this->AddTimestampComponent(c2, timeStruct, timeT, utcFlag,
|
||||
microseconds);
|
||||
++i;
|
||||
} else {
|
||||
result += c1;
|
||||
@@ -179,7 +179,7 @@ time_t cmTimestamp::CreateUtcTimeTFromTm(struct tm& tm) const
|
||||
}
|
||||
|
||||
std::string cmTimestamp::AddTimestampComponent(
|
||||
char flag, struct tm& timeStruct, const time_t timeT,
|
||||
char flag, struct tm& timeStruct, const time_t timeT, const bool utcFlag,
|
||||
const uint32_t microseconds) const
|
||||
{
|
||||
std::string formatString = cmStrCat('%', flag);
|
||||
@@ -203,6 +203,63 @@ std::string cmTimestamp::AddTimestampComponent(
|
||||
case 'Y':
|
||||
case '%':
|
||||
break;
|
||||
case 'Z':
|
||||
#if defined(__GLIBC__)
|
||||
// 'struct tm' has the time zone, so strftime can honor UTC.
|
||||
static_cast<void>(utcFlag);
|
||||
#else
|
||||
// 'struct tm' may not have the time zone, so strftime may
|
||||
// use local time. Hard-code the UTC result.
|
||||
if (utcFlag) {
|
||||
return std::string("GMT");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 'z': {
|
||||
#if defined(__GLIBC__)
|
||||
// 'struct tm' has the time zone, so strftime can honor UTC.
|
||||
static_cast<void>(utcFlag);
|
||||
#else
|
||||
// 'struct tm' may not have the time zone, so strftime may
|
||||
// use local time. Hard-code the UTC result.
|
||||
if (utcFlag) {
|
||||
return std::string("+0000");
|
||||
}
|
||||
#endif
|
||||
#ifndef _AIX
|
||||
break;
|
||||
#else
|
||||
std::string xpg_sus_old;
|
||||
bool const xpg_sus_was_set =
|
||||
cmSystemTools::GetEnv("XPG_SUS_ENV", xpg_sus_old);
|
||||
if (xpg_sus_was_set && xpg_sus_old == "ON") {
|
||||
break;
|
||||
}
|
||||
xpg_sus_old = "XPG_SUS_ENV=" + xpg_sus_old;
|
||||
|
||||
// On AIX systems, %z requires XPG_SUS_ENV=ON to work as desired.
|
||||
cmSystemTools::PutEnv("XPG_SUS_ENV=ON");
|
||||
tzset();
|
||||
|
||||
char buffer[16];
|
||||
size_t size = strftime(buffer, sizeof(buffer), "%z", &timeStruct);
|
||||
|
||||
# ifndef CMAKE_BOOTSTRAP
|
||||
if (xpg_sus_was_set) {
|
||||
cmSystemTools::PutEnv(xpg_sus_old);
|
||||
} else {
|
||||
cmSystemTools::UnsetEnv("XPG_SUS_ENV");
|
||||
}
|
||||
# else
|
||||
// No UnsetEnv during bootstrap. This is good enough for CMake itself.
|
||||
cmSystemTools::PutEnv(xpg_sus_old);
|
||||
static_cast<void>(xpg_sus_was_set);
|
||||
# endif
|
||||
tzset();
|
||||
|
||||
return std::string(buffer, size);
|
||||
#endif
|
||||
}
|
||||
case 's': // Seconds since UNIX epoch (midnight 1-jan-1970)
|
||||
{
|
||||
// Build a time_t for UNIX epoch and subtract from the input "timeT":
|
||||
|
||||
@@ -32,6 +32,6 @@ private:
|
||||
time_t CreateUtcTimeTFromTm(struct tm& timeStruct) const;
|
||||
|
||||
std::string AddTimestampComponent(char flag, struct tm& timeStruct,
|
||||
time_t timeT,
|
||||
uint32_t microseconds = 0) const;
|
||||
time_t timeT, bool utcFlag,
|
||||
uint32_t microseconds) const;
|
||||
};
|
||||
|
||||
22
Tests/CMakeTests/String-TIMESTAMP-TimeZone.cmake
Normal file
22
Tests/CMakeTests/String-TIMESTAMP-TimeZone.cmake
Normal file
@@ -0,0 +1,22 @@
|
||||
string(TIMESTAMP output "%z")
|
||||
|
||||
STRING(LENGTH output output_length)
|
||||
|
||||
message("~${output}~")
|
||||
|
||||
set(expected_output_length 6)
|
||||
|
||||
if(NOT(${output_length} EQUAL ${expected_output_length}))
|
||||
message(FATAL_ERROR "expected ${expected_output_length} entries in output with all specifiers; found ${output_length}")
|
||||
endif()
|
||||
|
||||
string(SUBSTRING ${output} 0 1 output0)
|
||||
string(SUBSTRING ${output} 4 1 output4)
|
||||
|
||||
if(NOT((${output0} STREQUAL "-") OR (${output0} STREQUAL "+")))
|
||||
message(FATAL_ERROR "expected output[0] equ '+' or '-'; found: '${output0}'")
|
||||
endif()
|
||||
|
||||
if(NOT((${output4} STREQUAL "0") OR (${output4} STREQUAL "5")))
|
||||
message(FATAL_ERROR "expected output[4] equ '0' or '5'; found: '${output4}'")
|
||||
endif()
|
||||
@@ -44,6 +44,8 @@ set(TIMESTAMP-IncompleteSpecifier-RESULT 0)
|
||||
set(TIMESTAMP-IncompleteSpecifier-STDERR "~foobar%~")
|
||||
set(TIMESTAMP-AllSpecifiers-RESULT 0)
|
||||
set(TIMESTAMP-AllSpecifiers-STDERR "~[0-9]+(;[0-9]+)*~")
|
||||
set(TIMESTAMP-TimeZone-RESULT 0)
|
||||
set(TIMESTAMP-TimeZone-STDERR "~[-,+][0-9][0-9][0-9][0-9]~")
|
||||
set(TIMESTAMP-MonthWeekNames-RESULT 0)
|
||||
set(TIMESTAMP-MonthWeekNames-STDERR "~[^%]+;[^%]+~")
|
||||
set(TIMESTAMP-UnixTime-RESULT 0)
|
||||
@@ -75,6 +77,7 @@ check_cmake_test(String
|
||||
TIMESTAMP-IncompleteSpecifier
|
||||
TIMESTAMP-AllSpecifiers
|
||||
TIMESTAMP-MonthWeekNames
|
||||
TIMESTAMP-TimeZone
|
||||
TIMESTAMP-UnixTime
|
||||
)
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
RESULT=2005-08-07 23:19:49.000000 Sunday=Sun August=Aug 05 day=219 wd=0 week=32 w_iso=31 %I=11 epoch=1123456789
|
||||
^RESULT=2005-08-07 23:19:49.000000 Sunday=Sun August=Aug 05 day=219 wd=0 week=32 w_iso=31 %I=11 epoch=1123456789 TZ=GMT tz=\+0000$
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
set(ENV{SOURCE_DATE_EPOCH} "1123456789")
|
||||
string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s" UTC)
|
||||
string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s TZ=%Z tz=%z" UTC)
|
||||
message("RESULT=${RESULT}")
|
||||
|
||||
Reference in New Issue
Block a user