🗓️ Úloha 8.3
Napíšte program, zdrojový kód, v jazyku C použitím štandardu C17, ktorý definuje štruktúru na reprezentáciu dátumu s položkami:
- deň (celé číslo)
- mesiac (celé číslo)
- rok (celé číslo)
Program by mal umožniť používateľovi zadať dva dátumy kde jednotlivé hodnoty dátumov sú definované v jednom riadku oddelené medzerou a vypočítať rozdiel medzi nimi. Rozdieľ je vypísaný ako počet dní medzi dátumami.
V programe ošetrite vstup od používateľa aby bolo možné zadať iba správny dátum (napríklad nie je možné zadať 31.2.) a zohľadňuje priestupné roky.
Príklady vstupov / výstupov programu
Priebeh programu môže vyzerať nasledovne:
Prvý dátum: 1 1 2023
Druhý dátum: 15 1 2024
---
Rozdiel dátumov: 376 dníPrvý dátum: 28 2 2020
Druhý dátum: 1 3 2020
---
Rozdiel dátumov: 2 dniBonus
Skúste upraviť výpis rozdielu dátumov tak aby uviedol pre používateľa rozdiel aj koľko prípadných rokov, mesiacov, či dní je medzi dátumami. Napríklad:
- vstup: 1.1.2023 a 15.1.2024 -> 1 rok a 15 dní
- vstup: 1.1.2022 a 5.3.2022 -> 2 mesiace a 5 dní
Rozbaľ pre ukážku riešenia
#include <stdio.h>
#include <stdlib.h>
// Štruktúra na reprezentáciu dátumu
typedef struct {
int day;
int month;
int year;
} Date;
// Počet dní v mesiacoch (pre bežné a priestupné roky)
const int daysInMonth[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, // Bežný rok
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} // Priestupný rok
};
// Funkcia na kontrolu, či je rok priestupný
int isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
// Funkcia na validáciu dátumu
int isValidDate(Date date) {
if (date.year < 1 || date.month < 1 || date.month > 12 || date.day < 1) {
return 0;
}
int leap = isLeapYear(date.year);
if (date.day > daysInMonth[leap][date.month - 1]) {
return 0;
}
return 1;
}
// Funkcia na prepočet dátumu na počet dní od začiatku referenčného bodu (napr. 1.1.0001)
int dateToDays(Date date) {
int totalDays = 0;
// Pridanie dní za celé roky
for (int i = 1; i < date.year; i++) {
totalDays += isLeapYear(i) ? 366 : 365;
}
// Pridanie dní za celé mesiace v aktuálnom roku
int leap = isLeapYear(date.year);
for (int i = 0; i < date.month - 1; i++) {
totalDays += daysInMonth[leap][i];
}
// Pridanie dní v aktuálnom mesiaci
totalDays += date.day;
return totalDays;
}
// Funkcia na výpočet rozdielu medzi dvoma dátumami
int calculateDateDifference(Date date1, Date date2) {
int days1 = dateToDays(date1);
int days2 = dateToDays(date2);
return abs(days1 - days2);
}
int main() {
Date date1, date2;
// Načítanie prvého dátumu
printf("Prvý dátum (deň mesiac rok): ");
scanf("%d %d %d", &date1.day, &date1.month, &date1.year);
if (!isValidDate(date1)) {
printf("Neplatný dátum! Zadajte správny dátum.\n");
return 1;
}
// Načítanie druhého dátumu
printf("Druhý dátum (deň mesiac rok): ");
scanf("%d %d %d", &date2.day, &date2.month, &date2.year);
if (!isValidDate(date2)) {
printf("Neplatný dátum! Zadajte správny dátum.\n");
return 1;
}
// Výpočet a výpis rozdielu
int difference = calculateDateDifference(date1, date2);
printf("---\nRozdiel dátumov: %d dní\n", difference);
return 0;
}Vysvetlenie
Štruktúra Date:
- Reprezentuje dátum s položkami day, month a year.
Priestupný rok:
- Funkcia isLeapYear kontroluje, či je rok priestupný, na základe pravidiel pre gregoriánsky kalendár.
Validácia dátumu:
- Funkcia isValidDate overuje, či zadaný dátum je platný (správny rozsah dní, mesiacov a rokov).
Prepočet dátumu na počet dní:
- Funkcia dateToDays konvertuje dátum na celkový počet dní od referenčného bodu (1.1.0001).
- Zahŕňa dni za celé roky, mesiace a aktuálny deň.
Rozdiel medzi dátumami:
- Funkcia calculateDateDifference vypočíta rozdiel v počte dní medzi dvoma dátumami.
Hlavný program:
- Používateľ zadá dva dátumy, ktoré sa validujú.
- Po výpočte rozdielu v dňoch je výsledok vypísaný.