找出当地时区与格林威治标准时间的时差分钟
find the local time zone’s difference from GMT in minutes
我的时区格式为 GMT+09:00 和 GMT+10:00。我正在使用 Linux (Open Suse) 和 C++17。
我想在几分钟内找出当地时区与 GMT 的时差。
这是我的示例程序。
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;
}
但我得到的是负数的差异,它们应该是正数。
----------- TZ Changed to GMT+08:00---------------
difference in mins =-480
TZ=GMT+08:00
----------- TZ Changed to GMT+09:30---------------
difference in mins =-570
TZ=GMT+09:30
----------- TZ Changed to GMT+10:00---------------
difference in mins =-600
TZ=GMT+10:00
----------- TZ Changed to GMT+10:30---------------
difference in mins =-630
TZ=GMT+10:30
----------- TZ Changed to GMT+11:00---------------
difference in mins =-660
TZ=GMT+11:00
为什么我让他们处于负面状态?
这些字符串被称为 POSIX 时区 ,并且是 defined here。这个定义说明了 UTC 偏移量:
If preceded by a '-', the timezone shall be east of the Prime Meridian; otherwise, it shall be west (which may be indicated by an optional preceding '+' ).
同时 std::put_time
是根据 C/Posix strftime
定义的,它说明了偏移量:
%z is replaced by the offset from UTC in the ISO 8601 format ‘‘−0430’’ (meaning 4
hours 30 minutes behind UTC, west of Greenwich), or by no characters if no time
zone is determinable. [tm_isdst]
总而言之,posix 时区字符串有一个约定(负数表示本初子午线 东),另一个约定适用于几乎所有其他人,包括其他人posix 的部分(负数表示本初子午线 西)。
所以您的代码实际上得到了正确答案。
Fwiw,这是一个 C++17 free, open-source, header-only Posix time zone library,它可以在不改变全局环境变量 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";
}
}
输出:
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
我的时区格式为 GMT+09:00 和 GMT+10:00。我正在使用 Linux (Open Suse) 和 C++17。 我想在几分钟内找出当地时区与 GMT 的时差。
这是我的示例程序。
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;
}
但我得到的是负数的差异,它们应该是正数。
----------- TZ Changed to GMT+08:00---------------
difference in mins =-480
TZ=GMT+08:00
----------- TZ Changed to GMT+09:30---------------
difference in mins =-570
TZ=GMT+09:30
----------- TZ Changed to GMT+10:00---------------
difference in mins =-600
TZ=GMT+10:00
----------- TZ Changed to GMT+10:30---------------
difference in mins =-630
TZ=GMT+10:30
----------- TZ Changed to GMT+11:00---------------
difference in mins =-660
TZ=GMT+11:00
为什么我让他们处于负面状态?
这些字符串被称为 POSIX 时区 ,并且是 defined here。这个定义说明了 UTC 偏移量:
If preceded by a '-', the timezone shall be east of the Prime Meridian; otherwise, it shall be west (which may be indicated by an optional preceding '+' ).
同时 std::put_time
是根据 C/Posix strftime
定义的,它说明了偏移量:
%z is replaced by the offset from UTC in the ISO 8601 format ‘‘−0430’’ (meaning 4 hours 30 minutes behind UTC, west of Greenwich), or by no characters if no time zone is determinable. [tm_isdst]
总而言之,posix 时区字符串有一个约定(负数表示本初子午线 东),另一个约定适用于几乎所有其他人,包括其他人posix 的部分(负数表示本初子午线 西)。
所以您的代码实际上得到了正确答案。
Fwiw,这是一个 C++17 free, open-source, header-only Posix time zone library,它可以在不改变全局环境变量 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";
}
}
输出:
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