C代码问题,更改10月最后一个星期日的标志以进行夏时制

时间:2019-04-26 11:51:31

标签: c

我在此站点上找到了一些代码,为了适应夏令时,我已对其进行了调整以在英国工作。计划是每小时运行一次,并相应地设置一个标志,然后将其增加一个小时或离开显示时间。系统时间将始终为GMT / UTC

#include <stdio.h>

int Year=2019;
int Month=10;
int Date=28;
int Dow=0;
char Hours=12;
char Mins=34;
char Seconds=0;
char DST=0;
const char * DAY[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};

int dayofweek(int d, int m, int y) 
{ 
static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; 
y -= m < 3; 
return ( y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
} 

int main()
{

Dow=0;
printf("dst check\n\n");
for(Date=1;Date<=31;Date++)
{

 Dow=dayofweek(Date, Month, Year);

 if ((Month  >  3 && Month < 10 ) || 
  (Month ==  3 && Date >=25 && Dow >= 6 && Dow == 0 && Hours >= 1) ||  // DST starts last Sunday of March;  1am
  (Month == 10 && Date <=25 && Dow <=6 && Dow >= 0) ||
  (Month == 10 && Date <=25 && Dow <=6 && Dow ==0 && Hours < 2)) {   // DST ends last Sunday of November; 2am
DST++;

 }
printf("Date %d:%d:%d",Date,Month,Year);
printf(" %s",DAY[Dow]);
printf(" GMT+%d\n",DST);
DST=0;
}
    return 0;
}

这是从今年10月的代码生成的输出,它应该检测10月的最后一个星期日并改回GMT / UTC,这似乎忽略了星期几。最后一个星期日只能在该月的25日至31日之间发生。我的代码似乎只占25位。该代码应在10月的最后一个星期日27日更改dst标志。

我正在嵌入式处理器上运行此代码,所以我不想使用time.h库。时间和日期变量将通过现有代码进行更新。

我的代码的输出。

  

dst检查

     

日期1:10:2019 GMT + 1星期二

     

日期2:10:2019 GMT + 1星期三

     

日期3:10:2019 GMT + 1星期四

     

日期4:10:2019星期五GMT + 1

     

日期5:10:2019星期六GMT + 1

     

日期6:10:2019星期日GMT + 1

     

日期7:10:2019星期一GMT + 1

     

日期8:10:2019 GMT + 1星期二

     

日期9:10:2019 GMT + 1星期三

     

日期10:10:2019 GMT + 1星期四

     

日期11:10:2019星期五GMT + 1

     

日期12:10:2019星期六GMT + 1

     

日期13:10:2019周日GMT + 1

     

日期14:10:2019星期一GMT + 1

     

日期15:10:2019星期二GMT + 1

     

日期16:10:2019 GMT + 1星期三

     

日期17:10:2019 GMT + 1星期四

     

日期18:10:2019星期五GMT + 1

     

日期19:10:2019星期六GMT + 1

     

日期20:10:2019星期日GMT + 1

     

日期21:10:2019星期一GMT + 1

     

日期22:10:2019星期二GMT + 1

     

日期23:10:2019格林尼治标准时间+1

     

日期24:10:2019格林尼治标准时间+1

     

日期25:10:2019星期五GMT + 1

     

日期26:10:2019星期六GMT + 0

     

日期27:10:2019星期日GMT + 0

     

日期28:10:2019星期一GMT + 0

     

日期29:10:2019星期二GMT + 0

     

日期30:10:2019格林尼治标准时间+0

     

日期31:10:2019格林尼治标准时间+0

1 个答案:

答案 0 :(得分:1)

我把OP问题当作难题。

为了简化起见,我使用了switch来区分3月和10月的特殊情况。

另一个技巧是,可以通过从月份的最后一天的日期中减去月份的最后一天的dayofweek()来轻松确定月份的最后一个星期日的日期。

对于有趣的3月和10月,日期是31。

这就是我得到的:

#include <stdio.h>

const char *const day[] = {
  "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"
};

int dayofweek(int d, int m, int y) 
{ 
  static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; 
  y -= m < 3; 
  return ( y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
} 

int dst(int d, int m, int y, int h)
{
  switch (m) {
    case 3: { // special case March
      // get date of last Sunday in March
      int dls = 31 - dayofweek(31, 3, y);
      return d != dls ? d > dls : h >= 1;
    }
    case 10: { // special case October
      // get date of last Sunday in October
      int dls = 31 - dayofweek(31, 10, y);
      return d != dls ? d < dls : h < 2;
    }
    default:
      return m > 3 && m < 10;
  }
}

void printDateDST(int d, int m, int y, int h)
{
  printf("Date: %2d.%2d.%4d (%s) %2d:00:00 DST %d\n",
    d, m, y, day[dayofweek(d, m, y)], h, dst(d, m, y, h));
}

int main()
{
  // check dst
  // some trivial cases
  for (int m = 1; m <= 12; ++m) printDateDST(10, m, 2019, 9);
  putchar('\n');
  // find edge cases
  int d3 = 0;
  for (int d = 24; d <= 31; ++d) {
    printDateDST(d, 3, 2019, 9);
    if (!d3 && dst(d, 3, 2019, 9)) d3 = d;
  }
  putchar('\n');
  int d10 = 0;
  for (int d = 24; d <= 31; ++d) {
    printDateDST(d, 10, 2019, 9);
    if (!d10 && !dst(d, 10, 2019, 9)) d10 = d;
  }
  putchar('\n');
  // on the edge
  for (int h = 0; h <= 3; ++h) printDateDST(d3, 3, 2019, h);
  putchar('\n');
  for (int h = 0; h <= 3; ++h) printDateDST(d10, 10, 2019, h);
  // done
  return 0;
}

输出:

Date: 10. 1.2019 (Th)  9:00:00 DST 0
Date: 10. 2.2019 (Su)  9:00:00 DST 0
Date: 10. 3.2019 (Su)  9:00:00 DST 0
Date: 10. 4.2019 (We)  9:00:00 DST 1
Date: 10. 5.2019 (Fr)  9:00:00 DST 1
Date: 10. 6.2019 (Mo)  9:00:00 DST 1
Date: 10. 7.2019 (We)  9:00:00 DST 1
Date: 10. 8.2019 (Sa)  9:00:00 DST 1
Date: 10. 9.2019 (Tu)  9:00:00 DST 1
Date: 10.10.2019 (Th)  9:00:00 DST 1
Date: 10.11.2019 (Su)  9:00:00 DST 0
Date: 10.12.2019 (Tu)  9:00:00 DST 0

Date: 24. 3.2019 (Su)  9:00:00 DST 0
Date: 25. 3.2019 (Mo)  9:00:00 DST 0
Date: 26. 3.2019 (Tu)  9:00:00 DST 0
Date: 27. 3.2019 (We)  9:00:00 DST 0
Date: 28. 3.2019 (Th)  9:00:00 DST 0
Date: 29. 3.2019 (Fr)  9:00:00 DST 0
Date: 30. 3.2019 (Sa)  9:00:00 DST 0
Date: 31. 3.2019 (Su)  9:00:00 DST 1

Date: 24.10.2019 (Th)  9:00:00 DST 1
Date: 25.10.2019 (Fr)  9:00:00 DST 1
Date: 26.10.2019 (Sa)  9:00:00 DST 1
Date: 27.10.2019 (Su)  9:00:00 DST 0
Date: 28.10.2019 (Mo)  9:00:00 DST 0
Date: 29.10.2019 (Tu)  9:00:00 DST 0
Date: 30.10.2019 (We)  9:00:00 DST 0
Date: 31.10.2019 (Th)  9:00:00 DST 0

Date: 31. 3.2019 (Su)  0:00:00 DST 0
Date: 31. 3.2019 (Su)  1:00:00 DST 1
Date: 31. 3.2019 (Su)  2:00:00 DST 1
Date: 31. 3.2019 (Su)  3:00:00 DST 1

Date: 27.10.2019 (Su)  0:00:00 DST 1
Date: 27.10.2019 (Su)  1:00:00 DST 1
Date: 27.10.2019 (Su)  2:00:00 DST 0
Date: 27.10.2019 (Su)  3:00:00 DST 0

Live Demo on coliru

根据OP问题中给出的事实进行计算。我没有检查这是否真的与任何位置的精确DST确定相符。