C++ timegm 将 DST 转换为未来某个给定时间的某个时区?

2024-04-09

我需要在我的班级中从 UTC 时间准确转换为给定时区的本地时间,无论 DST 是否有效。我的问题是,当我使用struct tm我必须提供 tm_isdst 成员,或者将其保留为 -1 以自动确定。

from mktime(3) - linux man page:
"The value specified in the tm_isdst field informs mktime() whether or not daylight saving time (DST) is in effect for the time supplied in the tm structure:
a positive value means DST is in effect;
zero means that DST is not in effect;
and a negative value means that mktime() should (use timezone information and system databases to) attempt to determine whether DST is in effect at the specified time.

现在这是我的问题。我正在与来自世界各地的交易所合作(来自芝加哥、纽约、圣保罗、墨尔本、布宜诺斯艾利斯、约翰内斯堡、上海、首尔......)。我有一个表,其中包含每个交易所的每个时区名称:例如非洲/约翰内斯堡、美国/芝加哥、美国/温尼伯。

我正在处理的数据是某些特定期货和期权金融工具的到期数据。我收到的数据始终采用 UTC 格式,我需要转换为交易所的本地时间。

长话短说,我当前的实现是为那些不应生效 DST 的资产的到期时间增加 1 小时(例如,在 12 月到期且当地时间为美国/芝加哥的工具,应添加 -360 分钟偏移量)和 DST 0,而另一个在同一时区的 6 月到期的应该有 -360 时区偏移 +60 DST 偏移,这将是 UTC 时间戳的 -300 偏移。我目前遇到的问题是,例如12 月,我得到的是上午 9:30,而不是上午 8:30,因为 UTC 时间戳已经包含 dst 偏移量。

这是我进行转换的函数,它显然已损坏:

#ifdef WIN32
#define timegm _mkgmtime
#endif

SimpleDateTime BusinessDateCalculator::UTC2TZ(const SimpleDateTime& utcDateTime, const int tz_utc_offset, const int tz_dst)
{
    struct tm stm;
    memset(&stm, 0, sizeof(stm));
    stm.tm_year = utcDateTime.getYear() - 1900;
    stm.tm_mon = utcDateTime.getMonth() - 1;
    stm.tm_mday = utcDateTime.getDay();
    stm.tm_hour = utcDateTime.getHour();
    stm.tm_min = utcDateTime.getMinute();
    stm.tm_sec = utcDateTime.getSecond();
    stm.tm_isdst = -1; //see note at the top of this file

    time_t tt = timegm( &stm );
    tt += (tz_utc_offset + tz_dst) * 60;

    struct tm ntm;
    memset(&ntm, 0, sizeof(ntm));
    gmtime_r( &tt, &ntm );
    return SimpleDateTime(ntm.tm_year + 1900, ntm.tm_mon + 1, ntm.tm_mday, ntm.tm_hour, ntm.tm_min, ntm.tm_sec, utcDateTime.getMillisecond());
}

其中 SimpleDateTime 是具有附加功能的日期时间类,例如从不同日期/时间格式(SQL、FIX、Timeonly、DateOnly)进行转换。

我随时都有某个交易所的时区信息。我的问题是我可以以某种方式提供时区名称,然后让timegm执行数据库搜索并确定美国/芝加哥时区的 DST 是否于 2014 年 12 月 19 日生效,因此不在 UTC 时间上添加额外的 60 分钟,并且在同一日期(例如在南部地区)半球时区 America/Sao_Paulo 的有效期至 2015 年 2 月 16 日,对于此时间戳,应添加 60 分钟以获得给定日期的正确当地时间。


当您通过 IANA 标识符引用时区时(例如"America/Chicago") - 已包含所有 DST 信息和时区的完整历史记录。至少,它在原始源数据中是这样的IANA 时区数据库 http://iana.org/time-zones.

你提到Boost http://www.boost.org/(在评论中)。虽然 Boost 确实支持这些类型的标识符,但它错误地认为它们是永久固定的。但事实并非如此,因为世界时区的偏移量和 DST 规则一直在变化。考虑到美国在 2007 年更改了 DST 规则,而俄罗斯则在今年晚些时候(2014 年 10 月)大幅更改了其时区。如果你看一下提升时区数据文件 https://github.com/boostorg/date_time/blob/master/data/date_time_zonespec.csv,您会看到它的格式剥离了所有历史记录,仅将每个标识符映射到一组规则。因此,我建议您这样做not使用 Boost 进行本地时区转换。

相反,请考虑使用ICU http://icu-project.org/。除此之外,它还包括时区转换功能,并使用 IANA 时区数据库的完整副本。你可以在这里阅读更多, http://userguide.icu-project.org/datetime/timezone并看到示例代码在这里。 http://userguide.icu-project.org/datetime/timezone/examples我对 C++ 不是特别熟练,但看来你可以使用 ICUCalendar类将 UTC 时间投影为特定时区的本地时间。

另一种选择是使用内置的时区函数GNU C 库 http://www.gnu.org/software/libc/documentation.html。它还使用完整时区数据库。有一个使用 IANA/Olson 标识符将 UTC 转换为本地时间的简单示例在这个网站上 http://rl.se/convert-utc-to-local-time,我也在下面发布了:

/*
    C source code example: Convert UTC to local time zone, considering daylight
    savings. Uses mktime(), gmtime() and localtime(). Works for dates between
    years 1902 and 2037. Should compile and run with any recent GNU C if your
    tzdata is healthy. Written by Robert Larsson  http://rl.se

    Code put in public domain; do what you want with it.
*/

#include    <stdio.h>
#include    <stdlib.h>
#include    <time.h>

#define     DESTZONE    "TZ=Europe/Stockholm"       // Our destination time zone

int main(void)
{
    struct tm   i;
    time_t      stamp;                              // Can be negative, so works before 1970

    putenv("TZ=UTC");                               // Begin work in Greenwich …

    i.tm_year = 2009-1900;                          // Populate struct members with
    i.tm_mon  = 8-1;                                // the UTC time details, we use
    i.tm_mday = 29;                                 // 29th August, 2009 12:34:56
    i.tm_hour = 12;                                 // in this example
    i.tm_min  = 34;
    i.tm_sec  = 56;

    stamp = mktime(&i);                             // Convert the struct to a Unix timestamp

    putenv(DESTZONE);                               // Switch to destination time zone

    printf("UTC  : %s", asctime(gmtime(&stamp)));
    printf("Local: %s", asctime(localtime(&stamp)));

    return 0;                                       // That’s it, folks.
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ timegm 将 DST 转换为未来某个给定时间的某个时区? 的相关文章

  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐

  • 使用spring构建Web项目时如何修复MojoFailureException

    最近我使用spring STS和roo 1 2 0 M1来构建一个web项目 我设置了 jpa 并创建了一个具有某些字段的实体 并为该实体创建了一个存储库和一个服务层 然后当我执行测试时 它给出了以下错误 roo gt perform te
  • MongoDB 查询速度过慢,即使查询很简单并且与索引对齐

    我正在运行一个 MongoDB 服务器 这实际上就是它运行的全部内容 该服务器拥有 64GB RAM 和 16 个内核 以及 2TB 硬盘空间 文档结构 数据库有一个集合domains拥有大约 2000 万份文档 每个文档中都有相当多的数据
  • SQL JOIN 查询编写

    我正在尝试编写一个涉及两个表的简单查询 人 表有其独特之处person id and a name 朋友 表有一个person id and a friend id这是一个 FK 到person id在人员表中 person
  • StringBuilder 真的比连接十几个字符串慢吗?

    StringBuilder 真的比连接十几个字符串慢吗 编译器如何优化字符串连接 使得使用 连接十几个字符串会比StringBuilder更好 从一本 本 沃森写的 书中说 字符串连接 用于简单连接已知的 在编译时 time 字符串数量 只
  • 在AngularJS控制器中转换日期格式

    我编写以下代码来打印当前日期时间 scope date new Date 然后我使用 console log 打印相同的内容 console log scope date 它工作正常 2017 年 1 月 24 日星期二 16 36 06
  • 带点运算符的常数 (VBA)

    我想要一个常量材料的目录 这样我就可以使用如下所示的代码 Dim MyDensity MySymbol MyDensity ALUMINUM Density MySymbol ALUMINUM Symbol 显然 铝的密度和符号预计不会改变
  • WP - 检查 wp_insert_post 之前是否存在帖子

    如何检查 wp insert post 之前的帖子是否存在以避免重复 如果我删除 if 语句 post exists 并继续重新插入产生多个重复的帖子 下面的代码就可以工作 我用 post exists 编写了 if 语句 只是为了开始实现
  • 如何禁用 phpmailer 在浏览器上显示配置详细信息

    我不知道为什么电子邮件配置详细信息和状态在成功发送电子邮件后显示在我的页面上 如何禁用它 消息 服务器 gt 客户端 220 mx google com ESMTP ss3sm18138445pab 43 gsmtp客户端 gt 服务器 E
  • 如何识别用户空间和内核空间之间的特定套接字?

    我在用户空间中有一个库 可以拦截套接字层调用 例如socket connect accept 等等 我只处理 TCP 套接字 在内核空间中 我有一个网络内核模块 它处理所有 TCP 连接 我需要能够在驱动程序中识别哪些套接字被用户空间库拦截
  • VIM 高亮匹配开始/结束

    我正在尝试找到一个插件 它将突出显示与 Verilog 匹配的开始 结束语句 VIM 可以使用花括号 方括号 但不能使用它的开始 结束 我希望 VIM 突出显示正确的开始到正确的结束 在我看来 最好的选择是使用 matchit 该脚本是 v
  • 如何在 docker exec bash 命令中转义引号

    我正在尝试在 docker 中执行 bash 命令 但我无法弄清楚如何转义表名周围的单引号user mappings在我的指挥下 我尝试过反斜杠 双单引号和双引号单引号 我知道如果我不将命令包装起来我可以绕过它bash c 但我需要它 以便
  • 使用 CA 文件从 Azure Database for MySQL 进行 SSL 连接

    跟随新 MySQL 服务的 Azure 文档 https learn microsoft com en us azure mysql howto configure ssl 看来您可以使用他们的受信任的 CA 证书非常简单地设置 SSL 按
  • Pod 更新后出现许多构建错误

    我的项目中安装了很多 pod 自从我上次更新 Pod 以来 一切都运行良好 上次 pod 更新后 我遇到了 28 个以 无法构建模块 xxx 开头的构建错误 这是我的 Podfile target projectXXX do use fra
  • Node.js 监听 MongoDB 变化

    Node js 有没有办法监听 MongoDB 集合中特定数据的更改 并在发生更改时触发事件 嗯 这是一个老问题 但我也在为同样的事情而苦苦挣扎 我发现了一些花絮帮助我构建了一个解决方案 并且我已将其作为库发布 https github c
  • document.head v. document.getElementsByTagName("head")[0]

    使用有什么区别document head并使用document getElementsByTagName head 0 我运行的测试表明它们都需要大约一毫秒 我也见过 document head document getElementsBy
  • 如何在结构字段上创建可变迭代器

    所以我正在使用 Rust 开发一个小型 NES 模拟器 并且我正在尝试使用我的状态寄存器 寄存器是一个结构体 其中包含一些包含布尔值的字段 标志 寄存器本身是 CPU 结构体的一部分 现在 我想循环这些字段并根据我执行的某些指令设置布尔值
  • 为什么 -std=c++98 标志有时不起作用?

    情况如下 我想创建一个简单的 C 程序 但它必须使用onlyC 98 函数 我在用Ubuntu 20 04 4 LTS 我在用c 作为编译器我使用以下标志进行编译 Wall Werror Wextra std c 98 pedantic e
  • JTabbedPane 自定义选项卡外观

    我想自定义 JTabbedPane 中选项卡的外观 我想从最简单 最朴素的行为开始 无边框 纯色 问题是仍然存在不平整的情况 选项卡的边距略有重叠 您会看到 由于选择了第二个选项卡 因此它被 带到了前台 这是通过轻微的边距重叠来实现的 有没
  • staruml 抽象类?

    有谁知道如何使用 StarUML 创建抽象类 我在文档中找不到任何提及 是否有某种反映抽象类的更一般的概念 从工具箱中选择类并将其添加到画布中 然后转到属性选择 isAbstract 复选框 然后类名显示为斜体
  • C++ timegm 将 DST 转换为未来某个给定时间的某个时区?

    我需要在我的班级中从 UTC 时间准确转换为给定时区的本地时间 无论 DST 是否有效 我的问题是 当我使用struct tm我必须提供 tm isdst 成员 或者将其保留为 1 以自动确定 from mktime 3 linux man