Вычислите количество дней между двумя датами,заданными в формате DD/MM/YYYY,включая начальный и конечный день. - C (СИ)
Формулировка задачи:
Вычислите количество дней между двумя датами,заданными в формате DD/MM/YYYY,включая начальный и конечный день. Даты могут быть заданы в произвольном порядке. Учитывайте високосные годы(такой год делится на 400 или делится на 4,но не делится на 100).
Написать нужно в трех файлах. data.h;data.c;main.c
Решение задачи: «Вычислите количество дней между двумя датами,заданными в формате DD/MM/YYYY,включая начальный и конечный день.»
textual
Листинг программы
//Вычислите количество дней между двумя датами,заданными в формате DD/MM/YYYY
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
struct DATE
{ int day;
int month;
int year;
};
int leapYear(int year)
{ return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
DATE *parseDate()
{ DATE *date = (DATE*) malloc(sizeof(DATE));
int checkInput;
char buf[15];
do
{ printf("\tFormatted as DD/MM/YYYY\t\t");
fgets(buf, 15, stdin);
checkInput = sscanf(buf, "%d/%d/%d", &date->day, &date->month, &date->year);
//проверка на ввод трех целых, разделенных слэшем
if(checkInput!=3)
{ printf("\nWrong date format\n");
continue;
}
//проверка на соответствие григорианскому календарю (принят в 1583)
if(date->year < 1583)
{ printf("\nThe Gregorian Calendar was adopted in 1583. Years before are irrelevant\n");
continue;
}
//проверка на попадание в ОДЗ
checkInput += date->day>0 && date->month>0 && date->month<= 12;
if(checkInput!= 4)
{ printf("\nImpossible value for day or month \n");
continue;
}
//проверка на взаимное соответствие день-месяц-год
if(leapYear(date->year) && date->month == 2)
checkInput += date->day <=29;
else
checkInput += date->day <= days [date->month-1];
//если последняя проверка не была пройдена
if(checkInput!= 5)
printf("\nDay-month-year mismatch\n");
} while(checkInput != 5);
return date;
}
int daysFromYearStart(DATE *date)
{ int sum = 0, i = 0;
for( ; i<date->month-1; i++)
sum += days [i];
sum += date->day;
if(leapYear(date->year) && date->month > 2)
sum++;
return sum;
}
int dateInDays(DATE *date)
{ int i = 1583, dateInDays = 365*(date->year - 1583);
for( ; i<date->year; i++)
if(leapYear(i)) dateInDays++;
dateInDays += daysFromYearStart(date);
return dateInDays;
}
int main()
{ DATE *d1, *d2;
printf("Date 1 ");
d1 = parseDate();
printf("Date 2 ");
d2 = parseDate();
printf("Difference in days: %d", abs(dateInDays(d1) - dateInDays(d2)));
free(d1); free(d2);
fflush(stdin);
getchar();
return 0;
}
Объяснение кода листинга программы
Код вычисляет разницу в количестве дней между двумя датами, введенными в формате DD/MM/YYYY. Он использует структуру DATE для хранения даты, функцию leapYear для определения, является ли год високосным, и функцию daysFromYearStart для вычисления количества дней в месяце или до определенной даты. Функция dateInDays вычисляет общее количество дней в заданной дате.
Список элементов кода:
- Объявление массива
days, содержащего количество дней в каждом месяце. - Объявление структуры
DATE, используемой для хранения даты. - Определение функции
leapYear, которая проверяет, является ли год високосным. - Определение функции
parseDate, которая считывает дату с консоли и проверяет ее корректность. - Определение функции
daysFromYearStart, которая вычисляет количество дней в месяце или до определенной даты. - Определение функции
dateInDays, которая вычисляет общее количество дней в заданной дате. - Ввод первой даты.
- Ввод второй даты.
- Вычисление разницы в количестве дней между двумя датами.
- Освобождение памяти, выделенной для хранения дат.
- Очистка буфера ввода.
- Возврат значения функции.