Как получить первое воскресенье года в с ++?

Я пытался получить дату первого воскресенья в этом году

int getFristSunday () {
    time_t rawtime;
    struct tm * timeinfo;
    time( &rawtime );
    timeinfo = localtime( &rawtime );
    timeinfo->tm_mon = 0;
    timeinfo->tm_wday = 0;
    mktime( timeinfo );
    return timeinfo->tm_yday ;
}

но я получаю первый четверг

Результат

3 ответа

Решение

Из этого mktime ссылка:

time-> tm_wday и time->tm_yday игнорируются.

Вы должны установить timeinfo->tm_mday в 1 а потом проверь какой день после звонка mktime и отсчитывать оттуда.

Используя эту бесплатную библиотеку C++11/14 с открытым исходным кодом, содержащую только заголовки:

#include "date.h"
#include <iostream>

int
main()
{
    using namespace date;
    std::cout << year_month_day{sun[1]/jan/2016} << '\n';
}

какие выводы:

2016-01-03

Есть year(), month() а также day() аксессоры для year_month_day объект. А алгоритмы высоко оптимизированы (не содержат итерационных циклов).

Если вы предпочитаете писать свои собственные вычисления дат, вот календарные алгоритмы общественного достояния, используемые в вышеупомянутой библиотеке дат. Ссылка ведет прямо к разделу, описывающему, как найти N-й день недели в комбинации месяц / год.

Перед звонком 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;
}
Другие вопросы по тегам