std::chrono::system_clock::now() 考虑操作系统配置的时区

2024-04-13

我正在编写在 BusyBox 嵌入式 Linux 上运行的 C++ 代码。我的代码及其库有多次调用std::chrono::system_clock::now()获取当前时间。

从现在开始,我的盒子已配置为默认时区(UTC),一切正常,进程运行且结果正常。

现在我必须将我的 Linux 设置为处于不同的时区。然后我通过在框中配置来完成/etc/profile:

export TZ=UTC+3

当我发出date命令和控制台我得到了正确的时间,但我的电话std::chrono::system_clock::now()我仍然得到 UTC 时间,而不是显示的时间date命令(正确的时间)。

我不想改变我的一切now()呼叫 - 有数百个......这导致我的进程的工作时间与控制台上设置的正确时间不同。

有什么办法可以在不改变我的代码的情况下解决这个问题吗?我在这里缺少什么吗?

谢谢你的帮助。


尽管标准未指定,但每次实施std::chrono::system_clock::now()正在追踪Unix时间 https://en.wikipedia.org/wiki/Unix_time,它非常接近 UTC。

如果你想翻译std::chrono::system_clock::now()到当地时间,你可以翻译system_clock::time_point to time_t via system_clock::to_time_t,然后通过 C API 进行操作(例如localtime),或者您可以尝试这个现代时区库,它构建在<chrono>:

https://howardhinnant.github.io/date/tz.html https://howardhinnant.github.io/date/tz.html

您可以使用它来获取当前本地时间,如下所示:

#include "tz.h"
#include <iostream>

int
main()
{
    using namespace date;
    using namespace std::chrono;
    auto t = make_zoned(current_zone(), system_clock::now());
    std::cout << t << '\n';
}

make_zoned是一个返回类型的工厂函数zoned_time无论你的精度如何system_clock支持(例如纳秒)。这是一对time_zone and a system_clock::time_point.

你可以获得一个local_time<Duration>这是一个std::chrono::time_point像这样:

    auto t = make_zoned(current_zone(), system_clock::now());
    auto lt = t.get_local_time();
    std::cout << lt.time_since_epoch().count() << '\n';

虽然该库有一个远程API来下载IANA 时区数据库 http://www.iana.org/time-zones自动地,可以通过编译来禁用该 API-DHAS_REMOTE_API=0。这一切都在安装说明 https://howardhinnant.github.io/date/tz.html#Installation。禁用远程 API 后,您必须从以下位置手动下载数据库:IANA 时区数据库 http://www.iana.org/time-zones(这只是一个tar.gz).

如果您需要当前的 UTC 偏移量,可以这样获取:

    auto t = make_zoned(current_zone(), system_clock::now());
    auto offset = t.get_info().offset;
    std::cout << offset << '\n';

在上面的代码片段中,我利用"chrono_io.h"在同一个 github 存储库中找到并打印offset. offset有类型std::chrono::seconds。这只是我的输出:

-14400s

(-0400)

最后,如果您想查找当前时区的 IANA 名称,只需:

std::cout << current_zone()->name() << '\n';

对我来说只是输出:

America/New_York

返回的类型来自name() is std::string。如果需要,可以记录该字符串,然后使用time_zone使用该名称,即使这不是计算机的当前时区:

auto tz_name = current_zone()->name();
// ...
auto t = make_zoned(tz_name, system_clock::now()); // current local time in tz_name

4年后更新

该库现已成为 C++20 的一部分,并进行了以下修改:

  • 的内容"tz.h" are in <chrono>.
  • 名称的内容在namespace date are in namespace std::chrono.
  • make_zoned不是 C++20 的一部分,因为CTAD https://en.cppreference.com/w/cpp/language/class_template_argument_deduction使它变得不必要。您可以使用zoned_time替换它的位置并推导模板参数。

此外,自定义(用户编写的)time_zone现在可以与https://howardhinnant.github.io/date/tz.html https://howardhinnant.github.io/date/tz.html或者使用新的 C++20<chrono>。一个很好的定制例子time_zone已写至此处为 POSIX 时区模型 https://github.com/HowardHinnant/date/blob/master/include/date/ptz.h。这可以用来更准确地回答原来的问题:

#include "date/ptz.h"
#include <cstdlib>
#include <iostream>

int
main()
{
    using namespace date;
    using namespace std;
    using namespace std::chrono;

    const char* tz = getenv("TZ");
    if (tz == nullptr)
        tz = "UTC0";
    zoned_time now{Posix::time_zone{tz}, system_clock::now()};
    cout << format("%F %T%z", now) << '\n';
}

With my TZ环境变量设置为UTC+3这只是我的输出:

2020-09-17 10:28:06.343050-0300

Notes:

  • 尽管依赖于tz.h, ptz.h是一个仅包含头文件的库。无需安装IANA tz数据库,也无需编译tz.cpp.

  • POSIX 指定 https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03UTC 偏移量的符号与其他所有内容(包括 POSIX 的其他部分)使用的符号相反。正偏移量是west本初子午线而不是east。这反映在本例中将 UTC 偏移量格式化为负数的输出中,这与POSIX strftime spec https://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html.

  • 如果使用 C++11 或 C++14 编译它,则没有CTAD https://en.cppreference.com/w/cpp/language/class_template_argument_deduction在你的工具箱里。在这种情况下:

`

zoned_time now{Posix::time_zone{tz}, system_clock::now()};

becomes:

zoned_time<system_clock::duration, Posix::time_zone> now{Posix::time_zone{tz}, system_clock::now()};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std::chrono::system_clock::now() 考虑操作系统配置的时区 的相关文章

随机推荐

  • 从 XML 创建实体

    我有以下 XML 结构
  • Django 中的脏字段

    在我的应用程序中 我需要在保存模型时保存更改的值 旧的和新的 有示例或工作代码吗 我需要这个来预先审核内容 例如 如果用户更改了模型中的某些内容 那么管理员可以在单独的表中查看所有更改 然后决定是否应用它们 我发现阿明的想法非常有用 这是我
  • Underscore.js - 在嵌套 Json 中进行过滤

    我想获取所有值 其中category id 1 所以我应该得到 2 个结果 我的 JSON 看起来像这样 var test id 1 name name1 value value1 category id 1 name category1
  • 不同用户类型的 Firebase Auth

    我正在开发一个有两个应用程序的项目 一个用于 请求者 用户 一个用于 响应者 用户 并且我目前正在使用 Firebase 进行身份验证 用户使用电子邮件 密码组合登录 这是问题的根源 问题在于用户冲突 因为身份验证模块连接到 Firebas
  • 如何在 TinyMCE 4 中创建一个增加字体大小的按钮

    有没有人设法在 TinyMCE 4 中创建一个按钮 该按钮会将所选文本的字体大小增加 例如 1px 我遇到的问题是获取选定的文本 无论它是否已经在跨度中 我愿意修改TinyMCE源代码 感谢您的任何想法 你不需要修改源代码 你可以创建一个插
  • WooCommerce 仅显示已购买的商品

    所以我在网上查了很多资料 但找不到解决方案 基本上我想做的是显示用户在商店中购买的所有产品的产品循环 就像显示普通产品一样 如果你还是不明白 也许这会帮助你明白我的意思 这是 WooCommerce 文档中的示例产品循环 ul class
  • 在移动设备中使用固定背景图像滚动时出现滞后

    我想要一个具有固定背景图像 大约 46k 的网站 该图像可以在我的 PC 浏览器上运行 然而 当在我的移动浏览器上滚动时 重绘背景图像需要大约一秒钟的时间 有什么想法可以解决这个问题吗 谢谢 这是我的CSS html body backgr
  • 如何获取 DLL 或 EXE 的文件描述

    我正在创建一个程序 其中之一是控制服务 我正在尝试以类似于中列出的方式列出服务msconfig 下面第一个窗口 我找到了注册表中列出的服务的位置 在 Vista 和 Win7 中 DisplayName 和 Description 通常是引
  • 无法将 SonarQube 分析结果与 VSTS 集成

    我正在 VSTS 中使用准备 运行和发布分析任务来运行 SonarQube 分析并发布结果以构建摘要 前两个步骤成功执行 但 发布分析 任务失败 因为它无法获取分析 ID 的任务 我收到以下错误消息 无法获取 ID AWE9 wu8 fbf
  • Swift:是否可以向协议添加协议扩展?

    假设我有两个协议 protocol TheirPcol protocol MyPcol func extraFunc 我想做的是为 TheirPcol 创建一个协议扩展 它可以让extraFunc 从事任何符合 TheirPcol 的事情
  • 多功能 SAM 模板的推荐项目结构

    我有一个新项目 需要相对少量的服务 可能是 10 个或更少 因此将每个服务放在单独的项目存储库中并不经济 每项服务都将通过 SAM 模板定义为 AWS Serverless Function 我的问题是 组织或构建这样一个项目的推荐方法是什
  • ag-grid - 删除具有无限行模型的行

    我正在尝试使用具有无限行模型和分页功能的网格来删除行 我不确定如何删除特定行并更新内部模型 而无需刷新网格 从而发出新的 ajax 请求 我已经读过这个线程 https github com ag grid ag grid issues 1
  • 将单独的年份和月份列合并为单个日期列

    我有一个像这样的数据框 df code year month 1 YYOOGG 2011 8 2 YYOOGG 2011 1 3 YYOOGG 2011 4 4 YYOOGG 2011 3 5 YYOOGG 2011 12 6 YYOOGG
  • 在 OS X 10.11 El Capitan、macOS 10.12 Sierra、macOS 10.13 High Sierra (< 10.13.3) 上安装 pecl 和 pear

    所以它看起来像新的 系统完整性保护 lockdown http arstechnica com apple 2015 09 os x 10 11 el capitan the ars technica review 8 usr 以及其他目录
  • 带有标题和子标题的导航抽屉菜单项

    我有一个导航抽屉原型 我们有相同的标题和副标题 我正在使用菜单组来包含标题 1 只想为导航抽屉添加子标题或帮助文本 2 想要自定义图标大小以适合整个标题和子标题 如下图所示
  • CMake:如何禁用单个 *.cpp 文件的优化?

    我想禁用 CMake 项目中单个 cpp 文件的优化 我发现 CMake 提供了以下功能来实现此目的 SET SOURCE FILES PROPERTIES FILE PROPERTIES COMPILE FLAGS O0 然而 这似乎对我
  • 如何检查列的值是否位于其他文件中两列的值之间并从 Unix 中的列中打印相应的值?

    我有两个文件要比较 我找到了如何比较列并根据条件进行打印 我手头的问题是 我必须检查 file1 中的 column 2 的值是否位于 file2 中定义为两列范围 col 2 col 3 的值之间 如果这是真的 那么我应该在 file1
  • 在打开表单之前设置所有标签字体

    在打开表单之前 我使用以下代码来检查其标签 然后更改字体 foreach Label ctl in frm Controls ctl Font usefontgrid 但在第一行返回错误 因为它检查其他控件类型 例如文本框或按钮等 如何检查
  • 为什么无法一步读取未对齐的单词?

    鉴于 CPU 的字大小允许它寻址内存中的每个字节 鉴于通过PAE http en wikipedia org wiki Physical address extensionCPU 甚至可以使用比字大小更多的位来进行寻址 CPU 无法一步读取
  • std::chrono::system_clock::now() 考虑操作系统配置的时区

    我正在编写在 BusyBox 嵌入式 Linux 上运行的 C 代码 我的代码及其库有多次调用std chrono system clock now 获取当前时间 从现在开始 我的盒子已配置为默认时区 UTC 一切正常 进程运行且结果正常