[RFC] libstdc++: chrono::current_zone() should always respect $TZ
James Morris
jamesmorris2@gmail.com
Sun May 7 21:55:15 GMT 2023
Hello,
I was playing around with GCC 13 and upgrading some old C++ code to
C++20. I had a small function for getting the current time based on
the <ctime> functions and tried to convert it to use the new <chrono>
functions. I was quite surprised that when using
chrono::current_zone(), my program stopped responding to the TZ
environment variable.
I'd like to propose that chrono::current_zone() always pays attention
to $TZ so as not to surprise users moving from <ctime>. tzdb.cc
already has code for this gated by an #ifdef, so maybe all that needs
to be done is to make that code available to all platforms.
Example of my code with <ctime>:
```
#include <ctime>
#include <iostream>
int main() {
std::time_t epoch_time = std::time(nullptr);
std::tm* local_time = std::localtime(&epoch_time);
char time_string[] = "00:00:00 UTC";
std::strftime(time_string, sizeof "00:00:00 UTC", "%T %Z", local_time);
std::cout << time_string << '\n';
}
```
Example of what I tried to do with <chrono>:
```
#include <chrono>
#include <format>
#include <iostream>
namespace chrono = std::chrono;
int main() {
auto zt = chrono::zoned_time(chrono::current_zone(),
chrono::system_clock::now());
std::cout << std::format("{:%T %Z}", zt) << '\n';
}
```
Diff of proposed changes:
```
diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc
index a43b4f33eba..c16913dab67 100644
--- a/libstdc++-v3/src/c++20/tzdb.cc
+++ b/libstdc++-v3/src/c++20/tzdb.cc
@@ -1632,6 +1632,20 @@ namespace std::chrono
{
// TODO cache this function's result?
+ // AIX stores current zone in $TZ in /etc/environment but the value
+ // is typically a POSIX time zone name, not IANA zone.
+ // https://developer.ibm.com/articles/au-aix-posix/
+ // https://www.ibm.com/support/pages/managing-time-zone-variable-posix
+ //
+ // Other POSIX systems also allow the user to override the
+ // system timezone by setting $TZ.
+ if (const char* env = std::getenv("TZ"))
+ {
+ // This will fail unless TZ contains an IANA time zone name.
+ if (auto tz = do_locate_zone(this->zones, this->links, env))
+ return tz;
+ }
+
#ifndef _AIX
error_code ec;
// This should be a symlink to e.g. /usr/share/zoneinfo/Europe/London
@@ -1685,17 +1699,6 @@ namespace std::chrono
return tz;
}
}
-#else
- // AIX stores current zone in $TZ in /etc/environment but the value
- // is typically a POSIX time zone name, not IANA zone.
- // https://developer.ibm.com/articles/au-aix-posix/
- // https://www.ibm.com/support/pages/managing-time-zone-variable-posix
- if (const char* env = std::getenv("TZ"))
- {
- // This will fail unless TZ contains an IANA time zone name.
- if (auto tz = do_locate_zone(this->zones, this->links, env))
- return tz;
- }
#endif
// Default to UTC.
```
Thanks,
James
More information about the Libstdc++
mailing list