LINUX.ORG.RU

end of month

 ,


0

1

Как максимально портабельно и желательно, без ручных вычислений получить последний день месяца для заданного tm, а лучше, для time_t?

★★★★★

Последнее исправление: cetjs2 (всего исправлений: 2)

get_lastday_of_month(time_t *time), и не благодари ;)

anonymous
()

Совсем без вычислений не знаю как, с ними я бы попробовал воспользоваться тем фактом, что mktime() нормализует поля своей входной структуры. Как-то так, учитывая что для декабря день года портится (код не проверял):

int
get_last_day_of_month(const struct tm *time)
{
    if (time->tm_mon == 11) {
        return 31;
    }

    struct tm tm = *time;
    tm.tm_mon += 1;    
    if (mktime(&tm) == (time_t)-1) {
        return -1;
    }
    return time->tm_mday + (tm.tm_yday - tm.tm_mday - time->tm_yday);
}

xaizek ★★★★★
()

а тебе точно последний день месяца нужен, первый день следующего не сойдёт? :)

Harald ★★★★★
()
Ответ на: комментарий от pon4ik

StackOverflow что ли? Сам писал, и не нахожу там такого с ходу. Я сначала в документацию в первую очередь смотрю, это хорошая привычка, советую :-)

xaizek ★★★★★
()
Ответ на: комментарий от mix_mix

Тем что там можно ошибиться. В случае со временем, там и так куча мест где можно накосячить (без всяких вычислений).

pon4ik ★★★★★
() автор топика
Ответ на: комментарий от xaizek

Гы. А я вчера первое что нагуглил - как раз этот совет. Думал ты решил его мне садаптировать. Там даже слова все те же +/-.

pon4ik ★★★★★
() автор топика
Ответ на: комментарий от Harald

Первый день месяца - константа же :)

Имеется ввиду - представление а не штамп.

pon4ik ★★★★★
() автор топика
int is_leap_year(int year)
{
    return ((!(year % 4)) && (year % 100)) || !(year % 400) ? 1 : 0;
}

int days_in_month(int year, int month)
{
    static const int days[2][12] = 
    {
        { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
        { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    };

    return days[is_leap_year(year)][month];
}

int days_in_tm(struct tm* t)
{
    return days_in_month(t->tm_year + 1900, t->tm_mon);
}


Дарю. Лучше потестируй, но должно быть как-то так.

Gvidon ★★★★
()
Ответ на: комментарий от pon4ik

Потому что чукча — работатель. В простых случаях написание своего велосипеда дешевле и гораздо эффективней долгих поисков «стандартных решений», вокруг которых часто ещё приходится городить башню из костылей. Это C, привыкай.

Gvidon ★★★★
()
Ответ на: комментарий от Gvidon

Смотря чего делаешь. Если либу опенсурсную то почему бы и нет.

pon4ik ★★★★★
() автор топика

Это делается при помощи mktime(), как вам уже советовали тут.

Только проще:

tm.tm_mon++;
tm.tm_mday = 0;
mktime(&tm);

return (tm.tm_mday);

Sorcerer ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.