Я пытаюсь записать класс Даты в попытке изучить C++.
Я пытаюсь найти, что алгоритм добавляет или вычитает дни на дату, откуда День запускается 1, и Месяц запускается от 1. Это оказывается очень сложным, и Google не появляется очень,
Кто-либо знает об алгоритме, который делает это?
Самый простой способ - написать две функции: одна преобразует день в число дней с заданной даты начала, а другая преобразует обратно в дату. Как только дата выражается в количестве дней, ее легко прибавлять или вычитать.
Вы можете найти алгоритмы здесь: http://alcor.concordia.ca/~gpkatch/gdate-algorithm.html
Я предполагаю, что это какое-то упражнение, иначе вы бы использовали класс времени, который вам уже предоставлен.
Вы можете сохранить свое время как количество миллисекунд с определенной даты. А затем вы можете добавить соответствующее значение и преобразовать его в дату при вызове методов доступа вашего класса.
Я бы предложил сначала написать процедуру, которая преобразует год-месяц-день в количество дней с фиксированной даты, скажем, с 1.01.01. И симметричная процедура, которая преобразует его обратно.
Не забывайте правильно обрабатывать високосные годы!
Имея эти два, ваша задача была бы тривиальной.
Вот набросок очень простой подход. Для простоты идей я предполагаю, что 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.
Вам действительно не нужен алгоритм как таковой (по крайней мере, не что-то достойное такого названия), стандартная библиотека может сделать большую часть тяжелой работы; каландровые вычисления заведомо сложны. Если вам не нужны даты раньше 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 ;
}
Один из подходов - сопоставьте дату с юлианским числом даты, выполните целочисленные операции и затем преобразуйте обратно.
Вы найдете множество ресурсов по функциям julian.