0

我想要 C++ 中的灵魂来获得 GMT 时间和任何时区之间的小时差异。例如,这是我想用 C++ 制作的 Java

// New York
Calendar c = new GregorianCalendar(TimeZone.getTimeZone("America/New_York"));  

// Alaska  
c = new GregorianCalendar(TimeZone.getTimeZone("America/Anchorage"));
// Difference between New York and Alaska  

请告诉我如何在 C++ 中获得这个时区

4

2 回答 2

2

您可以使用cctz库来计算某个特定时间两个不同时区之间的 UTC 偏移差异。

#include <chrono>
#include "cctz.h"
using namespace std::chrono;

cctz::TimeZone nyc;
cctz::LoadTimeZone("America/New_York", &nyc);

cctz::TimeZone anc;
cctz::LoadTimeZone("America/Anchorage", &anc);

const auto now = system_clock::now();
const auto nyc_off = cctz::BreakTime(now, nyc).offset;
const auto anc_off = cctz::BreakTime(now, anc).offset;

const auto off_diff = nyc_off - anc_off;

现在,事实是你真的不想那样做。真的。健康、现代的代码永远不应该(我说从不,因为我的意思是从不)关心 UTC 偏移量。使用 UTC 偏移量计算是你的时区库的工作,如果你的时区库不能为你处理,那么你使用了错误的时区库。如果您认为您关心 UTC 偏移量,那么我鼓励您查看以下内容:

  • 在其 github 页面上阅读 CCTZ 的基本概念部分
  • 观看CppCon 2015 的时间编程基础
  • 阅读 cctz.h 头文件(简短而简单)

[免责声明:我是 cctz 的作者。]

于 2015-10-26T13:29:37.493 回答
1

几天来,我一直在盯着Greg 的好答案,并正在考虑在我的时区库中添加一些语法糖:

namespace date
{

class zoneverter
{
    const Zone* zp1_;
    const Zone* zp2_;

public:
    zoneverter(const Zone* z1, const Zone* z2)
        : zp1_(z1)
        , zp2_(z2)
        {}

    zoneverter(const Zone* z1, const std::string& z2)
        : zoneverter(z1, locate_zone(z2))
        {}

    zoneverter(const std::string& z1, const Zone* z2)
        : zoneverter(locate_zone(z1), z2)
        {}

    zoneverter(const std::string& z1, const std::string& z2)
        : zoneverter(locate_zone(z1), locate_zone(z2))
        {}

    template <class Rep, class Period>
    auto
    operator<<(std::chrono::time_point<std::chrono::system_clock,
                                       std::chrono::duration<Rep, Period>> tp) const
    {
        return zp1_->to_local(zp2_->to_sys(tp)).first;
    }
};

}  // namespace date

这添加了一个“流式对象”,它允许std::chrono::time_point通过它流式传输 a 以将其从一个时区转换为另一个时区。这是一个非常简单的设备,除了添加一些语法糖外,什么都不做,但会从我的时区库中删除一些信息。

它将像这样使用:

int
main()
{
    // So things don't get overly verbose
    using namespace date;
    using namespace std::chrono;

    // Set up the zone converters:
    zoneverter nyc_from_utc{"America/New_York",  "UTC"};
    zoneverter anc_from_nyc{"America/Anchorage", "America/New_York"};

    // Get the current time in New York and convert that to the current time in Anchorage
    auto now_nyc = nyc_from_utc << system_clock::now();
    auto now_anc = anc_from_nyc << now_nyc;

    // Output the difference
    std::cout << make_time(now_nyc - now_anc) << '\n';
}

这目前为我输出:

04:00:00.000000

我也不确定这种语法糖是否比当前语法好到足以保证它的存在:

int
main()
{
    // So things don't get overly verbose
    using namespace date;
    using namespace std::chrono;

    // Set up the zones:
    auto nyc_zone = locate_zone("America/New_York");
    auto anc_zone = locate_zone("America/Anchorage");

    // Get the current time in New York and the current time in Anchorage
    auto now_utc = system_clock::now();
    auto now_nyc = nyc_zone->to_local(now_utc).first;
    auto now_anc = anc_zone->to_local(now_utc).first;

    // Output the difference
    std::cout << make_time(now_nyc - now_anc) << '\n';
}
于 2015-11-02T01:18:33.773 回答