创建 CTime @ 2am 不会返回正确的值(Windows CE,C++)

Creating a CTime @ 2am doesn't return the correct value (Windows CE, C++)

本文关键字:Windows CE C++ 2am CTime 返回 创建      更新时间:2023-10-16

这违背了所有合理的逻辑,但是当我尝试构造一个包含"2"的CTime小时时,它将在小时字段中返回1而不是2。仅适用于此小时值。平台是WindowsCE 6.0,普通的c ++(VS2005)

void main(void)
{
CTime       myTime;
int         myMonth;
for(myMonth=1; myMonth < 13; myMonth++)
{
myTime = CTime(2017, 03, 12, myMonth, 0, 0, 0); 
printf("Month: %d", myMonth);
printf("r");
printf("CTime: %d, %d, %d, %d, %d, %d", myTime.GetYear(), myTime.GetMonth(), myTime.GetDay(), myTime.GetHour(), myTime.GetMinute(), myTime.GetSecond());
printf("r");
}
}

月份: 1

CTime: 2017, 3, 12, 1, 0, 0

月: 2

CTime: 2017, 3, 12, 1, 0, 0//!!

月: 3

CTime: 2017

, 3, 12, 3, 0, 0月: 4

CTime: 2017, 3, 12, 4, 0, 0

月: 5

CTime: 2017, 3, 12, 5, 0, 0

月: 6

CTime: 2017, 3, 12, 6, 0, 0

月: 7

CTime: 2017, 3, 12, 7, 0, 0

月: 8

CTime: 2017, 3, 12, 8, 0, 0

月: 9

CTime: 2017, 3, 12, 9, 0, 0

月: 10

CTime: 2017, 3, 12, 10, 0, 0

月: 11

CTime: 2017, 3, 12, 11, 0, 0

月: 12

CTime: 2017, 3, 12, 12, 0, 0

添加分钟和秒有效,但小时仍然不好。

nDST 可以是 -1、0 或 1,也可以省略(构造函数默认为 -1),它不会改变任何内容,如果在 2 处输入,小时仍将设置为 1。

相当令人沮丧。

另外,我尝试了其他方法:

CTime    myCurrentTime = CTime::GetCurrentTime();   

你猜怎么着?如果确实是凌晨 2 点,则此构造函数正常工作,并在小时中输入"2"。

-> 我目前正在扫描我构建的 DST 转换表,我需要构造一个时间参考,将其与当前时间进行比较,并决定是将当前条目放入表中还是跳到下一个条目。

由于内存占用,使用任何外部插件库都不是解决方案。我被 CE 6.0 和 10 年前设计的电路板所困。有一个"香草"c++ 解决方案会很好。

实际上(假设美国时区)时钟向前跳跃,而不是回到 2017-03-12 02:00:00,这使得CTime的输出相当好奇。

假设有一个现代编译器(例如VS-2013或更好),这里有一个C++11/14库,可以用来澄清情况。

#include "chrono_io.h"
#include "tz.h"
#include <iostream>
#include <exception>
int
main()
{
try
{
using namespace date;
using namespace std::chrono_literals;;
for (auto myHour = 1h; myHour < 13h; ++myHour)
{
auto myTime = make_zoned(current_zone(),
local_days{2017_y/mar/12} + myHour);
std::cout << "Hour: " << myHour << 'n';
std::cout << "Time: " << myTime << 'n';
}
}
catch (const std::exception& e)
{
std::cout << e.what() << 'n';
}
}

我试图保留原始程序的结构,但我更改了一些误导性的变量名称和标签。

该程序的输出(在具有美国时区的计算机上运行)为:

Hour: 1h
Time: 2017-03-12 01:00:00 EST
2017-03-12 02:00:00 is in a gap between
2017-03-12 02:00:00 EST and
2017-03-12 03:00:00 EDT which are both equivalent to
2017-03-12 07:00:00 UTC

上面错误消息中提到的"间隙"是本地时间的半开放范围,包括开始时间,但不包括结束时间([2:00:00, 3:00:00))。

错误消息说明出了什么问题,但如果您不想出现异常,则不会说明如何修复它。 如果您不想要异常,您可以稍微更改上述程序以"预先决定"如何处理本地时间的不连续性。

如果本地时间不明确(在同一日期发生两次),则可以指定要更早或更晚的时间。 例如,从夏令时过渡到标准夏令时会发生这种情况。 从标准时间过渡到夏令时,本地时间会向前跳转(通常跳过一小时)。 发生这种情况时,间隙的两侧对应于同一时刻。 由于差距是半开放的,因此据说本地时间会从 1:59:59.999999 跳到 3:00:00。

在"弹簧前向"方案中,您可以指定需要"较早"或"较晚"映射,并且两者都映射到位于间隙两侧的 UTC-instant,在此示例中,当转换回本地时间时,该时间为 3:00:00。

在代码中,这看起来像:

#include "chrono_io.h"
#include "tz.h"
#include <iostream>
#include <exception>
int
main()
{
try
{
using namespace date;
using namespace std::chrono_literals;;
for (auto myHour = 1h; myHour < 13h; ++myHour)
{
auto myTime = make_zoned(current_zone(),
local_days{2017_y/mar/12} + myHour,
choose::earliest); // only change
std::cout << "Hour: " << myHour << 'n';
std::cout << "Time: " << myTime << 'n';
}
}
catch (const std::exception& e)
{
std::cout << e.what() << 'n';
}
}

和输出:

Hour: 1h
Time: 2017-03-12 01:00:00 EST
Hour: 2h
Time: 2017-03-12 03:00:00 EDT
Hour: 3h
Time: 2017-03-12 03:00:00 EDT
Hour: 4h
Time: 2017-03-12 04:00:00 EDT
Hour: 5h
Time: 2017-03-12 05:00:00 EDT
Hour: 6h
Time: 2017-03-12 06:00:00 EDT
Hour: 7h
Time: 2017-03-12 07:00:00 EDT
Hour: 8h
Time: 2017-03-12 08:00:00 EDT
Hour: 9h
Time: 2017-03-12 09:00:00 EDT
Hour: 10h
Time: 2017-03-12 10:00:00 EDT
Hour: 11h
Time: 2017-03-12 11:00:00 EDT
Hour: 12h
Time: 2017-03-12 12:00:00 EDT

现在重复3am而不是1am(CTime),但至少你知道为什么,并且默认情况下会收到详细的错误消息。

处理当地时间的所有诡计可能是一项棘手的工作,但这个库可以帮助您处理它。 顺便说一下,几天后我们有一个闰秒。 如果该细节对您的时间计算很重要,该库还可以处理该细节。

视频介绍:https://www.youtube.com/watch?v=Vwd3pduVGKY

从文档中:


CTime( int, int, ...);从本地时间组件构造一个 CTime 对象,每个组件都限制在以下范围内......

在 2017 年 3 月 12 日晚上,当时钟敲到凌晨 2 点时,DST 开始,您的时钟实际上回到凌晨 1 点。该函数将您的输入解释为冬令时凌晨 2 点(因为它不知道您是否是指 DST,但必须以某种方式选择一个!),但是当您GetHour()结果日期的小时部分时,现在是凌晨 1 点......因为你在夏天。

这就是为什么在当地工作是一场噩梦!如果可以的话,尝试找到一个UTC替代方案。标准C++有一些相当不错的时间处理功能,您可以使用这些功能来代替专有Microsoft的东西。