gpt4 book ai didi

c++ - 时间偏移计算偏差一分钟

转载 作者:行者123 更新时间:2023-11-30 02:31:39 25 4
gpt4 key购买 nike

我正在尝试用一个统一的 API 替换许多不同的时间类。但是我最近遇到了一个问题,我无法正确序列化时区偏移量。请注意,我正在尝试复制已在系统中广泛使用的现有格式。

格式应为YYYY-mm-DD HH:MM:SS.xxxxxxx -HHMM,其中x代表亚秒精度,最后一个-HHMM 是与 UTC 的 TZ 偏移量。

代码:

using namespace My::Time;
namespace chrn = std::chrono;
time_point now = clock::now();
time_point lclNow = getDefaultCalendarProvider()->toLocal(now);
duration diff{ lclNow - now };
std::wstring sign = diff > duration::zero() ? L" +" : L" -";
duration ms{ now.time_since_epoch().count() % duration::period::den };
int diffHrs = popDurationPart<chrn::hours>(diff).count();
int diffMins{ abs(chrn::duration_cast<chrn::minutes>(diff).count()) };
std::cout << Format{ lclNow, TimeZone::UTC, L" %Y-%m-%d %H:%M:%S." } << ms.count()
<< sign << std::setfill(L'0') << std::setw(2) << diffHrs
<< std::setfill(L'0') << std::setw(2) << diffMins << std::endl;

问题:

Expected:<2016-05-25 09:45:18.1970000 +0100> Actual:< 2016-05-25 09:45:18.1964787 +0059>

期望值是我用老类做同样的操作得到的值。问题似乎出在我试图区分 lclNownow 之间。

目前我处于 UTC +1(由于 DST 生效)。但是,diff 值始终为 35999995635。在 Windows 中的 Visual C++ 上,滴答是 100 ns,所以每秒有 10000000 个滴答,这意味着 diff 值是 3599.9995 秒,这刚好比我需要的 3600 秒少一个小时.

当我使用相同的格式打印两个时间值时,我可以看到它们恰好相隔一小时。所以看来时区转换不是问题。

最佳答案

这个问题似乎来自于我尝试的时区转换(正如 SamVarshavchik 指出的那样)。不幸的是,我无法使用 Howard Hinnant 的非常完整的 date and tz libraries因为他们需要一种机制来更新他们工作所需的 IANA 时区数据库,所以我求助于包装 Windows native 调用以进行时区转换;即TzSpecificLocalTimeToSystemTimeSystemTimeToTzSpecificLocalTime功能。

但是这些只适用于 SYSTEMTIME而不是 time_point。这意味着我采取了将 time_point 转换为 FILETIME(只需修改“epoch”)并将 FILETIME 转换为SYSTEMTIME 在将其传递给上述两个函数之一之前。这导致时间值在被插入 SYSTEMTIME 结构(仅保持毫秒分辨率)时被截断。结果是,虽然我的日期是准确的,但在将日期转换回原始值时我并不完全准确。

新的解决方案没有将基本的 time_point 转换为 time_point 的日历映射。它使用以下代码计算出 std::chrono::minutes 中的偏移量(其中 zoneInfoTIME_ZONE_INFORMATION ):

time_point WindowsTzDateProvider::doToUtc(const time_point& inLocal) const {
return inLocal + getBias(inLocal);
}

time_point WindowsTzDateProvider::doToLocal(const time_point& inUtc) const {
return inUtc - getBias(inUtc);
}

std::chrono::minutes WindowsTzDateProvider::doGetBias(const time_point& input) const {
bool isDst = CalendarDateProvider::isDstInEffect(input);
minutes baseBias{ zoneInfo.Bias };
minutes extraBias{ isDst ? zoneInfo.DaylightBias : zoneInfo.StandardBias };
return baseBias + extraBias;
}

bool CalendarDateProvider::isDstInEffect(const time_point& t) {
time_t epochTime = clock::to_time_t(t);
tm out;
#ifdef WIN32
localtime_s(&out, &epochTime);
#else
localtime_r(&out, &epochTime);
#endif
return out.tm_isdst > 0;
}

注意:我对类使用非虚拟接口(interface)惯用语,因此使用“do...”版本的方法。

关于c++ - 时间偏移计算偏差一分钟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37434159/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com