C# 不使用库和系统调用计算夏令时

C# 不使用库和系统调用计算夏令时,c#,c++,date,time,C#,C++,Date,Time,所以,我为一个只有RTC的系统编码,RTC包含星期一、天、年、小时、分钟、秒和星期几 没有漂亮的库和系统调用,我试图创建一种方法,根据美国/加拿大规则和墨西哥规则简单地计算它是否是DST 如果美国的规则是3月2日第二个星期日凌晨2点到11月2日第一个星期日凌晨2点,那么该代码是否是实现这一点的最佳方法 switch (TestDateTime->Month) { case 1: case 2: case 12: // January, Februar

所以,我为一个只有RTC的系统编码,RTC包含星期一、天、年、小时、分钟、秒和星期几

没有漂亮的库和系统调用,我试图创建一种方法,根据美国/加拿大规则和墨西哥规则简单地计算它是否是DST

如果美国的规则是3月2日第二个星期日凌晨2点到11月2日第一个星期日凌晨2点,那么该代码是否是实现这一点的最佳方法

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月1日星期日凌晨2点到10月2日最后一个星期日凌晨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;
}
我假设其中一个代码是好的,我认为可能是这样。或者,它可以在以后的讨论中帮助其他人(如果是或不是)。

此示例使用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 CST和凌晨1:30 CDT


<>我知道你的代码是C++,但你也标记了这个C,我猜想C的解决方案是可以接受的——不难将这个方法翻译成你的上下文

根据一些大假想的奇想,DST的细节每年都不会改变吗?好吧,这是许多用算法几乎无法解决的日期/时间问题之一,必须从数据库中提取。@delnan不是每一个近,甚至不是每一个近。不过,这些规则确实偶尔会改变,所以要知道,如果你像这样硬编码,你的代码最终可能需要改变。好吧,是的,这就是为什么让它成为可升级应用程序的一部分要比依赖第三方编译器制造商提供的库要好得多。这就是为什么我要问这个问题,如果上述观点对我以外的人来说是正确的,那么也许其他嵌入式开发人员也可以使用其背后的思想。我同意以后必须更改,因为这是政府批准该软件的必要条件。亚利桑那州有一些例外:当可以使用类型bool时,为什么要使用未签名的8位返回值?您可以使用标准布尔值:true和false。