Алгоритм, чтобы добавить или вычесть дни из даты?

Я пытаюсь записать класс Даты в попытке изучить C++.

Я пытаюсь найти, что алгоритм добавляет или вычитает дни на дату, откуда День запускается 1, и Месяц запускается от 1. Это оказывается очень сложным, и Google не появляется очень,

Кто-либо знает об алгоритме, который делает это?

20
задан bcoughlan 26 February 2010 в 19:41
поделиться

6 ответов

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

Вы можете найти алгоритмы здесь: http://alcor.concordia.ca/~gpkatch/gdate-algorithm.html

19
ответ дан 29 November 2019 в 23:52
поделиться

Я предполагаю, что это какое-то упражнение, иначе вы бы использовали класс времени, который вам уже предоставлен.

Вы можете сохранить свое время как количество миллисекунд с определенной даты. А затем вы можете добавить соответствующее значение и преобразовать его в дату при вызове методов доступа вашего класса.

3
ответ дан 29 November 2019 в 23:52
поделиться

Я бы предложил сначала написать процедуру, которая преобразует год-месяц-день в количество дней с фиксированной даты, скажем, с 1.01.01. И симметричная процедура, которая преобразует его обратно.

Не забывайте правильно обрабатывать високосные годы!

Имея эти два, ваша задача была бы тривиальной.

0
ответ дан 29 November 2019 в 23:52
поделиться

Вот набросок очень простой подход. Для простоты идей я предполагаю, что d , количество дней, которое нужно добавить, положительно. Нижеследующее легко распространить на случаи, когда d отрицательно.

Либо d меньше 365, либо d больше или равно 365.

Если d меньше 365:

m = 1;
while(d > numberOfDaysInMonth(m, y)) {
    d -= numberOfDaysInMonth(m, y);
    m++;
}
return date with year = y, month = m, day = d;

Если d больше 365:

while(d >= 365) {
    d -= 365;
    if(isLeapYear(y)) {
        d -= 1;
    }
    y++;
}
// now use the case where d is less than 365

В качестве альтернативы, вы можете выразить дату, скажем, в юлианской форме , а затем просто добавить к юлианской форме и преобразовать в формат ymd.

2
ответ дан 29 November 2019 в 23:52
поделиться

Вам действительно не нужен алгоритм как таковой (по крайней мере, не что-то достойное такого названия), стандартная библиотека может сделать большую часть тяжелой работы; каландровые вычисления заведомо сложны. Если вам не нужны даты раньше 1900 года, тогда:

#include <ctime>

// Adjust date by a number of days +/-
void DatePlusDays( struct tm* date, int days )
{
    const time_t ONE_DAY = 24 * 60 * 60 ;

    // Seconds since start of epoch
    time_t date_seconds = mktime( date ) + (days * ONE_DAY) ;

    // Update caller's date
    // Use localtime because mktime converts to UTC so may change date
    *date = *localtime( &date_seconds ) ; ;
}

Пример использования:

#include <iostream>

int main()
{
    struct tm date = { 0, 0, 12 } ;  // nominal time midday (arbitrary).
    int year = 2010 ;
    int month = 2 ;  // February
    int day = 26 ;   // 26th

    // Set up the date structure
    date.tm_year = year - 1900 ;
    date.tm_mon = month - 1 ;  // note: zero indexed
    date.tm_mday = day ;       // note: not zero indexed

    // Date, less 100 days
    DatePlusDays( &date, -100 ) ; 

    // Show time/date using default formatting
    std::cout << asctime( &date ) << std::endl ;
}
13
ответ дан 29 November 2019 в 23:52
поделиться

Один из подходов - сопоставьте дату с юлианским числом даты, выполните целочисленные операции и затем преобразуйте обратно.

Вы найдете множество ресурсов по функциям julian.

1
ответ дан 29 November 2019 в 23:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: