Я сделал светодиодные настенные часы & Календарь основан на Arduino некоторое время назад, и теперь я хочу изменить его, чтобы добавить в переменную, чтобы автоматически настроить смещение для летнего времени. Я уже опрашиваю интернет-сервер времени 2 раза в день, чтобы гарантировать точность, но серверы времени обычно не предоставляют информацию о летнем времени. Изменение происходит во второе воскресенье марта и первое воскресенье ноября. (https://www.nist.gov/pml/time-and-frequency-division/popular-links/daylight-saving-time-dst) По сути, мне нужно знать, когда наступит второе воскресенье марта, и попросить его настроить смещение часового пояса на +1, а затем на -1 в первое воскресенье ноября. Я просто не уверен, как это реализовать.
Я думаю что-то вроде:
если
месяц == 3 или 11
А ТАКЖЕ
если будний день == 1;
затем
воскресенье + 1;
еще
воскресенье = 0;
если воскресенье == 2;
А ТАКЖЕ
месяц == 3;
затем
isDST = TRUE;
если воскресенье == 1;
А ТАКЖЕ
месяц == 11;
затем
isDST = FALSE;
Я надеюсь, что это достаточно хороший пример того, что я хочу сделать. Я ненавижу использовать так много вложенных if, но это лучшее, что я могу придумать, оставаясь относительным новичком. Будет ли это даже работать или есть лучший способ сделать это? Любая помощь с этим будет принята с благодарностью.
Вот бумага с календарными алгоритмами это может быть использовано для вычисления таких вещей, как второе воскресенье марта. Увидеть Пример: поиск n-го дня недели месяца.
Если у вас есть C ++ 11, вы можете использовать это бесплатная библиотека дат с открытым исходным кодом вычислять такие вещи с синтаксисом очень высокого уровня. Библиотека использует алгоритмы из бумага под капотом. Например:
std::chrono::system_clock::time_point
DST_US(std::chrono::system_clock::time_point tp, std::chrono::hours std_offset)
{
using namespace date;
using namespace std::chrono;
const auto y = year_month_day{floor<days>(tp)}.year();
const auto begin = sys_days{sun[2]/mar/y} + 2h - std_offset; // DT begins at this UTC time
const auto end = sys_days{sun[1]/nov/y} + 1h - std_offset; // ST begins at this UTC time
if (tp < begin || end <= tp)
return tp + std_offset;
return tp + std_offset + 1h;
}
Не стесняйтесь использовать библиотеку datetime, если у вас есть C ++ 11 (она переносима), и создавать свои собственные, используя алгоритмы в бумага иначе.
Отказ от ответственности: правила часовых поясов все время меняются. Вышесказанного вполне достаточно для самодельных часов. Для промышленных приложений, нуждающихся в современных правилах часовых поясов, используйте библиотеку, основанную на База данных часовых поясов IANA такие как этот.
Здесь я сделал код C ++ для вас. Вам не нужен C ++ 11 для запуска этого.
Как это работает, он получает текущий месяц и год. Проверяет, является ли год високосным, затем устанавливает максимальное количество дней. Допустим, 2017 год август. Максимальный день будет 31.
Программа начинает работать и считает sundayCounter
вверх, если день поражения воскресенье.
Таким образом, вы получите количество воскресений в текущем месяце автоматически.
Вот мой код, не стесняйтесь использовать его. Это именно то, что вы хотите сделать. Ваша желаемая переменная sundayCounter
, Повеселись.
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
bool isLeap = false;
int sundayCounter = 0;
int MAX_DAY;
int month, year;
string monthText;
time_t theTime = time(NULL);
struct tm *aTime = localtime(&theTime);
month = aTime->tm_mon;
year = aTime->tm_year;
if (year % 4 == 0)
{;
if (year % 100 == 0)
{
if (year % 400 == 0)
isLeap = true;
else
isLeap = false;
}
else
isLeap = true;
}
else {
isLeap = false;
}
switch(month)
{
case 0:
MAX_DAY = 31;
break;
case 1:
if(isLeap)
MAX_DAY = 29;
else
MAX_DAY = 28;
break;
case 2:
MAX_DAY = 31;
break;
case 3:
MAX_DAY = 30;
break;
case 4:
MAX_DAY = 31;
break;
case 5:
MAX_DAY = 30;
break;
case 6:
MAX_DAY = 31;
break;
case 7:
MAX_DAY = 31;
break;
case 8:
MAX_DAY = 30;
break;
case 9:
MAX_DAY = 31;
break;
case 10:
MAX_DAY = 30;
break;
case 11:
MAX_DAY = 31;
break;
}
for(int day = 0; day <= MAX_DAY; day++) {
struct tm time_in = { 0, 0, 0, // second, minute, hour
day, month + 1, year - 1900 }; // 1-based day, 0-based month, year since 1900
time_t time_temp = mktime( & time_in );
// the return value from localtime is a static global - do not call
// this function from more than one thread!
tm const *time_out = localtime( & time_temp );
switch(time_out->tm_wday)
{
case 0:
sundayCounter++;
break;
}
}
const char* month_list[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
int current_month = month+1;
const char* current_month_name = month_list[current_month-1];
cout << "Sunday amount in " << current_month_name << " " << (year + 1900) << ": " << sundayCounter;
cout << endl;
return 0;
}
Выход:
Sunday amount in August 2017: 4