Проблема с кодом C, чтобы поменять флаг в последнее воскресенье октября для перехода на летнее время - PullRequest
3 голосов
/ 26 апреля 2019

Я нашел код на этом сайте, который я настроил для работы в Великобритании для перехода на летнее время.План состоит в том, чтобы запускать его один раз в час и устанавливать соответствующий флаг, который затем добавляет час или оставляет как есть, отображаемое время.Системное время всегда будет 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;
}

Это вывод, сгенерированный из кода с октября этого года, он должен обнаружить последнее воскресенье октября и вернуться обратно к GMT / UTC, кажетсяигнорировать день недели.Последнее воскресенье может происходить только между 25 и 31 числами месяца.Кажется, мой код забрал 25-е.Код должен изменить флаг dst 27-го числа - последнее воскресенье октября.

Я запускаю этот код на встроенном процессоре, поэтому я не хочу использовать библиотеку time.h.Переменные времени и даты будут обновлены существующим кодом.

Вывод из моего кода.

Проверка DST

Дата 1: 10: 2019 Вторник по Гринвичу + 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 понедельник по Гринвичу + 1

Дата 15: 10: 2019 вторник по Гринвичу + 1

Дата 16: 10: 2019 среда по Гринвичу + 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 среда GMT + 1

Дата 24: 10: 2019 четверг GMT + 1

Дата 25: 10: 2019 пятница по Гринвичу + 1

Дата 26: 10: 2019 суббота по Гринвичу + 0

Дата 27: 10: 2019 воскресенье по Гринвичу + 0

Дата 28: 10: 2019 понедельник по Гринвичу + 0

Дата 29: 10: 2019 вторник по Гринвичу + 0

Дата 30: 10: 2019 среда по Гринвичу + 0

Дата31: 10: 2019 четверг по Гринвичу + 0

1 Ответ

1 голос
/ 26 апреля 2019

Я взял вопрос ОП как загадку.

Чтобы упростить его, я использовал switch, чтобы выделить особые случаи марта и октября.

Другой трюк заключается в том, чтодата последнего воскресенья месяца может быть легко определена путем вычитания dayofweek() последнего дня месяца из даты последнего дня месяца.

Для интересных месяцев марта и октября дата составляет 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

Живая демоверсия на coliru

Расчеты выполняются в соответствии с фактами, приведенными в вопросе ОП.Я не проверял, действительно ли это соответствует точному определению летнего времени для любого местоположения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...