Перед тем как позвонить mktime()
, необходимо указать все поля, кроме tm_yday
и tm_wday
. Очевидно, что мы должны установить tm_mon
и tm_mday
для 1 января
Важно установить tm_hour
в полдень (12) и/или tm_isdst
-1 застраховать пересчитывается время не влияет на летнее время. Подумайте, что произойдет, если текущее время было около полуночи и установки летнего времени на данный момент отличался от 1 января Повторного расчет может подтолкнуть время от 1 января до 2 января или Дека 31.
int getFirstSunday(void) {
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
timeinfo->tm_mon = 0; // set to January which is 0 "Months since January"
timeinfo->tm_mday = 1; // Set to the 1st of the month
timeinfo->tm_hour = 12; // Set to avoid getting the wrong DST setting for Jan 1.
timeinfo->tm_isdst = -1; // Set to avoid getting the wrong DST setting for Jan 1.
if (mktime(timeinfo) == -1) return -1;
int DaysSinceSundayForJan1 = timeinfo->tm_wday; // days since Sunday — [0, 6]
int DaysAfterJan1toNextSunday = 7 - DaysSinceSundayForJan1;
int DaysAfterJan1toFirstSunday = DaysAfterJan1toNextSunday%7;
// Convert to "day of the month"
return DaysAfterJan1toFirstSunday + 1;
}
Пуска с Яном -1, и итерации, пока вы не доберетесь до воскресенья. Это не займет больше шести итераций. – dasblinkenlight
@dasblinkenlight как 'mktime()' работает во время локали, установка на 1 января может быть недостаточной, так как 'mktime()' может отобразить это до 2 января из-за разницы между установкой DST теперь и 1 января и «сейчас», около полуночи. В зависимости от того, как выполняются итерации, может возникнуть ответ от 8 января. Необходимость обеспечения правильности DST не меняет дату. – chux