所以,我正在编写一个只有一个包含星期一,日,年,小时,分钟,秒和星期几的RTC的系统。
如果没有好的库和系统调用,我正在尝试根据美国/加拿大规则和墨西哥规则创建一种简单计算是否为夏令时的方法。
这段代码是美国的最佳方式,规则是“3月2日凌晨2点到11月2日凌晨1点”
switch (TestDateTime->Month)
{
case 1:
case 2:
case 12:
// January, February and December are definitely NOT DST months
u8RetVal = FALSE;
break;
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
// April, May, June, July, August, September, October are definitely FULL DST months
u8RetVal = TRUE;
break;
case 3:
// At this point, this is March is a partial DST month
i8PreviousSunday = TestDateTime->DayOfMonth - TestDateTime->DayOfWeek;
// In march, we are DST if our previous sunday was on or after the 8th.
if (i8PreviousSunday >= 8)
{
// So if it is the 2nd week of March and the day is a Sunday, check the time for less than 2AM, if so, it isn't DST yet
if ((TestDateTime->DayOfMonth >= 8) && (TestDateTime->DayOfMonth <= 14) && (TestDateTime->DayOfWeek == 0) && (TestDateTime->Hours < 2))
{
u8RetVal = FALSE;
}
else
{
u8RetVal = TRUE;
}
}
else
{
u8RetVal = FALSE;
}
break;
case 11:
// At this point, this is November is a partial DST month
i8PreviousSunday = TestDateTime->DayOfMonth - TestDateTime->DayOfWeek;
// In november we must be before the first sunday to be in DST. That means the previous sunday must be before the 1st.
if (i8PreviousSunday <= 0)
{
// This falls on the Monday-Saturday before the first Sunday, so we are still DST
u8RetVal = TRUE;
}
else
{
// This falls on the first Sunday and later. So, a catch for the Sunday of the first week, if not 2AM yet, we are still DST.
if ((TestDateTime->DayOfMonth >= 1) && (TestDateTime->DayOfMonth <= 7) && (TestDateTime->DayOfWeek == 0) && (TestDateTime->Hours < 2))
{
u8RetVal = TRUE;
}
else
{
u8RetVal = FALSE;
}
}
break;
default:
// Invalid Month
u8RetVal = FALSE;
break;
}
然后在墨西哥,规则是4月2日的第一个星期日到10月2日的上个星期日。
switch (TestDateTime->Month)
{
case 1:
case 3:
case 2
case 11:
case 12:
// January, February, March, November and December are definitely NOT DST months
u8RetVal = FALSE;
break;
case 5:
case 6:
case 7:
case 8:
case 9:
// May, June, July, August, September are definitely FULL DST months
u8RetVal = TRUE;
break;
case 4:
// At this point, this is April is a partial DST month
i8PreviousSunday = TestDateTime->DayOfMonth - TestDateTime->DayOfWeek;
// In march, we are DST if our previous sunday was on or after the 1st.
if (i8PreviousSunday >= 1)
{
// So if it is the 2nd week of March and the day is a Sunday, check the time for less than 2AM, if so, it isn't DST yet
if ((TestDateTime->DayOfMonth >= 1) && (TestDateTime->DayOfMonth <= 7) && (TestDateTime->DayOfWeek == 0) && (TestDateTime->Hours < 2))
{
u8RetVal = FALSE;
}
else
{
u8RetVal = TRUE;
}
}
else
{
u8RetVal = FALSE;
}
break;
case 10:
// At this point, this is October is a partial DST month
i8PreviousSunday = TestDateTime->DayOfMonth - TestDateTime->DayOfWeek;
// In October we must be before the last Sunday, which will always be one of the last 7 days
if (i8PreviousSunday <= 24)
{
// This falls on the Monday-Saturday before the first Sunday, so we are still DST
u8RetVal = TRUE;
}
else
{
// This falls on the first Sunday and later. So, a catch for the Sunday of the first week, if not 2AM yet, we are still DST.
if ((TestDateTime->DayOfMonth >= 25) && (TestDateTime->DayOfMonth <= 31) && (TestDateTime->DayOfWeek == 0) && (TestDateTime->Hours < 2))
{
u8RetVal = TRUE;
}
else
{
u8RetVal = FALSE;
}
}
break;
default:
// Invalid Month
u8RetVal = FALSE;
break;
}
我假设代码是好的,我认为它可能是。或者它可以在以后通过讨论帮助其他人。如果它是或不是。
答案 0 :(得分:0)
此示例使用C#的DateTime
类,但也应该使用您的代码:
public static DateTime GetDay(int year, int month, int ordinal,
DayOfWeek dayOfWeek, bool fromStart)
{
DateTime result = new DateTime(year, month, 1);
if (!fromStart)
result = result.AddMonths(1).AddDays(-1);
int mult = fromStart ? 1 : -1;
for (; result.DayOfWeek != dayOfWeek; result = result.AddDays(1 * mult));
for (int i = 1; i < ordinal; result = result.AddDays(7 * mult), i++);
return result;
}
// use like this
// meaning: in 2013, in March, find the second Sunday, from the beginning
GetDay(2013, 3, 2, DayOfWeek.Sunday, true); // US start, Mar 10
GetDay(2013, 11, 1, DayOfWeek.Sunday, true); // US end, Nov 3
GetDay(2013, 4, 1, DayOfWeek.Sunday, true); // MX start, Apr 7
// meaning: in 2013, in October, find the first Sunday, from the end
GetDay(2013, 10, 1, DayOfWeek.Sunday, false); // MX end, Oct 27
然后,一些简单的日期比较将告诉您目标时间是否为DST,DST周围的小时数除外。这变得更复杂,你真的需要存储比你说的更多的信息,例如存储UTC时间戳,然后在需要时将其转换,例如区分美国中部时间凌晨1:30和CDT凌晨1:30“退回”日。
(我知道你的代码是C ++,但是你也标记了这个C#,我认为C#解决方案是可以接受的 - 将这个方法翻译成你的上下文应该不难)