Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 查找本地时区’;s与格林尼治标准时间之差(分钟)_C++_Linux_C++17_Timezone Offset_Chrono - Fatal编程技术网

C++ 查找本地时区’;s与格林尼治标准时间之差(分钟)

C++ 查找本地时区’;s与格林尼治标准时间之差(分钟),c++,linux,c++17,timezone-offset,chrono,C++,Linux,C++17,Timezone Offset,Chrono,我有GMT+09:00和GMT+10:00格式的时区。我正在使用Linux(开放Suse)和C++17。 我试图找出当地时区与格林尼治标准时间的差异,以分钟为单位 这是我的示例程序 static constexpr time_t const NULL_TIME = -1; // returns difference in mintues long tz_offset(time_t when = NULL_TIME) { if (when == NULL_TIME) when = s

我有GMT+09:00和GMT+10:00格式的时区。我正在使用Linux(开放Suse)和C++17。 我试图找出当地时区与格林尼治标准时间的差异,以分钟为单位

这是我的示例程序

static constexpr time_t const NULL_TIME = -1;

// returns difference in mintues
long tz_offset(time_t when = NULL_TIME) {
  if (when == NULL_TIME)
    when = std::time(nullptr);
  auto const tm = *std::localtime(&when);
  std::ostringstream os;
  os << std::put_time(&tm, "%z");
  std::string s = os.str();
  // s is in ISO 8601 format: "±HHMM"
  int h = std::stoi(s.substr(0, 3), nullptr, 10);
  int m = std::stoi(s[0] + s.substr(3), nullptr, 10);
  return h * 60 + m;
}

int main() {
  for (auto &timezone :  {"GMT+08:00", "GMT+09:30", "GMT+10:00", "GMT+10:30", "GMT+11:00"}) {
    setenv("TZ", timezone, 1);
    tzset();
    std::cout << "----------- TZ Changed to " << timezone << "---------------\n";
    std::cout << "difference in mins =" << tz_offset() << std::endl;
    auto tz_env_var = getenv("TZ");
    if (tz_env_var != nullptr) {
      std::cout << "TZ=" << tz_env_var << "\n";
    }
  }

  return 0;
}

有没有任何指针说明我为什么要将它们设置为负数?

这些字符串被称为POSIX时区,并且是负数。此定义说明了UTC偏移:

如果前面有“-”,则时区应位于本初子午线以东;否则,它应该是西边(可以用可选的前面的“+”表示)

同时,
std::put_time
是根据C/Posix
strftime
定义的,它表示偏移量:

%z替换为ISO 8601格式的UTC偏移量“”−0430''(意思是4 格林威治以西UTC落后小时30分钟),如果没有时间,则不允许出现任何字符 区域是可确定的。[tm_isdst]

总之,posix时区字符串有一个约定(本初子午线的负向表示),而其他几乎所有人都有一个约定,包括posix的其他部分(本初子午线的负向表示西

因此,您的代码实际上得到了正确的答案

Fwiw,这里是一个可以在不更改全局环境变量TZ的情况下执行作业的函数,并使用更简单的语法:

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

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

    for (auto &timezone : {"GMT+08:00", "GMT+09:30", "GMT+10:00", "GMT+10:30", "GMT+11:00"})
    {
        auto offset = Posix::time_zone{timezone}.get_info(system_clock::now()).offset;
        std::cout << "difference is " << duration_cast<minutes>(offset) << '\n';
        std::cout << "TZ is " << timezone << "\n\n";
    }
}

你允许使用哪种版本的C++?我用C++来定义它。字符串中的偏移量与
tz_offset()
函数给出的偏移量相反。请看手册页。这是因为两个标准(时区的书写方式和
tz_offset()
函数的定义)都来自不同的、不相关的地方。如果你考虑了欧洲时区(如<代码> GMT-03AX这里),你将看到正面的<代码> TZYOFSESET()/<代码>。谢谢,Howard Hinnant解释。这意味着如果我需要澳大利亚地区的当地时区与格林尼治标准时间的差异,那么我必须使用“GMT-08:00”、“GMT-09:30”。
#include "date/ptz.h"
#include <chrono>
#include <iostream>

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

    for (auto &timezone : {"GMT+08:00", "GMT+09:30", "GMT+10:00", "GMT+10:30", "GMT+11:00"})
    {
        auto offset = Posix::time_zone{timezone}.get_info(system_clock::now()).offset;
        std::cout << "difference is " << duration_cast<minutes>(offset) << '\n';
        std::cout << "TZ is " << timezone << "\n\n";
    }
}
difference is -480min
TZ is GMT+08:00

difference is -570min
TZ is GMT+09:30

difference is -600min
TZ is GMT+10:00

difference is -630min
TZ is GMT+10:30

difference is -660min
TZ is GMT+11:00