以线程安全的方式转换 C/C++ 中时区名称字符串的时区偏移量
Converting timezone offset from timezone name string in C/C++ in a thread-safe way
我正在尝试实现一个函数,以便可以转换给定的时区名称字符串,它确实如此:
- 接受输入时区字符串,例如"澳大利亚/墨尔本";
- 检查主机操作系统(假设它是 POSIX 环境(时区数据库;
- 返回时区偏移量的整数(对于 DST 中的墨尔本,为 36000(。
这可以通过调用putenv("TZ=Australia/Melbourne")
来完成,但这可能不是线程安全的。
有没有办法在不putenv()
的情况下做到这一点,或者以某种方式让它成为线程安全的?提前感谢!
由于编译器还不支持 C++20std::chrono
库的所有功能,我将编写一个使用 Howard Hinnantdate
https://github.com/HowardHinnant/date 库的解决方案。C++20 介绍了可用于实现所需目标的std::chrono::zoned_time
。
#include "date/tz.h"
#include <iostream>
int main()
{
auto current_time = std::chrono::system_clock::now();
auto la = date::zoned_time{"America/Los_Angeles", current_time};
auto sy = date::zoned_time{"Australia/Sydney", current_time};
std::cout << date::format("%Tn", sy.get_local_time() - la.get_local_time());
}
上面的示例将为您提供两个时区之间的差异。此外,如果您想获取当前操作系统的时区,您可以使用我希望将来编译器会支持的东西 -std::chrono::time_zone::name
。
在 C++20 中,您将能够使用std::chrono::tzdb::locate_zone()
,它将给定的时区名称转换为可以查询以获取偏移量的std::chrono::time_zone
对象。
没有处理时区的标准 C 函数。有符合 POSIX.1 的函数,但它们确实不是线程安全的。但是,根据您的操作系统,您可能能够打开时区数据库文件并手动分析它们。例如,在 Linux 上,您可以打开/usr/share/zoneinfo/Australia/Melbourne
并根据它在 tzfile(5( 手册页中的规范对其进行解析。
除了OP的线程问题之外,另一个考虑因素:
"时区与时区名称字符串的偏移量"通常是不够的,因为偏移量因全年的数据/时间而异。
即使所选区域中没有发生年度日光调整,偏移量也可能因区域的历史而异。
long offset(tz_name)
是不够的,还需要long offset(tz_name, time_t t)
。
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 通过指针偏移量访问结构变量值
- 以线程安全的方式转换 C/C++ 中时区名称字符串的时区偏移量
- librdkafka:rd_kafka_assignment 返回分配分区的偏移量 -1001
- 是否通过向封闭对象的地址添加字节偏移量来访问子对象
- 向指针地址添加 20 个字节偏移量
- glMapBufferRange(..) 中的偏移量关系和 glDrawArraysInstanced(..) 中的第一
- 是否有与 C# Structs/StructLayout 等效的功能,C++中的字段偏移量?
- 我的 sumASCII 函数中的此偏移量是多少?
- boost::序列化中的派生类偏移量计算.有效吗?
- RedisGraph 语法错误在偏移量 8 靠近"创建"
- 胎面偏移量的时间复杂度?
- 如何从 c++ 中的给定标准输入中获取每个字符的偏移量?
- 编译器在构造函数中计算的成员偏移量不正确
- 使用基地址和偏移量获取变量的地址
- c++ 读取进程内存基址 + 偏移量不起作用
- 通过其在 C 中的偏移量调用函数
- 如何获取特定日期某个地点的时区(偏移量)
- 从c++中的时区名称获取时区偏移量
- 在Mac(C++)上获取系统时区的UTC偏移量