Task: Days between dates


C++: #include <iomanip>
#include <iostream>

class Date {
private:
    int year, month, day;

public:
    Date(std::string str) {
        if (isValidDate(str)) {
            year = atoi(&str[0]);
            month = atoi(&str[5]);
            day = atoi(&str[8]);
        } else {
            throw std::exception("Invalid date");
        }
    }

    int getYear() {
        return year;
    }

    int getMonth() {
        return month;
    }

    int getDay() {
        return day;
    }

    
    static bool isValidDate(std::string str) {
        if (str.length() != 10 || str[4] != '-' || str[7] != '-') {
            return false;
        }

        if (!isdigit(str[0]) || !isdigit(str[1]) || !isdigit(str[2]) || !isdigit(str[3])) {
            return false; 
        }
        if (!isdigit(str[5]) || !isdigit(str[6])) {
            return false; 
        }
        if (!isdigit(str[8]) || !isdigit(str[9])) {
            return false; 
        }

        int year = atoi(&str[0]);
        int month = atoi(&str[5]);
        int day = atoi(&str[8]);

        
        if (year <= 0 || month <= 0 || day <= 0) {
            return false;
        }
        if (month > 12) {
            return false;
        }

        switch (month) {
        case 2:
            if (day > 29) {
                return false;
            }
            if (!isLeapYear(year) && day == 29) {
                return false;
            }
            break;
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            if (day > 31) {
                return false;
            }
            break;
        default:
            if (day > 30) {
                return false;
            }
            break;
        }

        return true;
    }

    static bool isLeapYear(int year) {
        if (year > 1582) {
            return ((year % 4 == 0) && (year % 100 > 0))
                || (year % 400 == 0);
        }
        if (year > 10) {
            return year % 4 == 0;
        }
        
        return false;
    }

    friend std::ostream &operator<<(std::ostream &, Date &);
};

std::ostream &operator<<(std::ostream &os, Date &d) {
    os << std::setfill('0') << std::setw(4) << d.year << '-';
    os << std::setfill('0') << std::setw(2) << d.month << '-';
    os << std::setfill('0') << std::setw(2) << d.day;
    return os;
}

int diffDays(Date date1, Date date2) {
    int d1m = (date1.getMonth() + 9) % 12;
    int d1y = date1.getYear() - d1m / 10;

    int d2m = (date2.getMonth() + 9) % 12;
    int d2y = date2.getYear() - d2m / 10;

    int days1 = 365 * d1y + d1y / 4 - d1y / 100 + d1y / 400 + (d1m * 306 + 5) / 10 + (date1.getDay() - 1);
    int days2 = 365 * d2y + d2y / 4 - d2y / 100 + d2y / 400 + (d2m * 306 + 5) / 10 + (date2.getDay() - 1);

    return days2 - days1;
}

int main() {
    std::string ds1 = "2019-01-01";
    std::string ds2 = "2019-12-02";

    if (Date::isValidDate(ds1) && Date::isValidDate(ds2)) {
        Date d1(ds1);
        Date d2(ds2);
        std::cout << "Days difference : " << diffDays(d1, d2);
    } else {
        std::cout << "Dates are invalid.\n";
    }

    return 0;
}










Ada: with Ada.Calendar;
with Ada.Text_IO;
with Ada.Integer_Text_IO;

with GNAT.Calendar.Time_IO;

procedure Days_Between_Dates is

   function Days_Between (Lower_Date  : in Ada.Calendar.Time;
                          Higher_Date : in Ada.Calendar.Time) return Integer
   is
      use Ada.Calendar;
      Diff : constant Duration := Higher_Date - Lower_Date;
   begin
      return Integer (Diff / Day_Duration'Last);
   end Days_Between;

   procedure Put_Days_Between (Lower_Date  : in String;
                               Higher_Date : in String;
                               Comment     : in String)
   is
      use Ada.Text_IO;
      use Ada.Integer_Text_IO;
      use GNAT.Calendar.Time_IO;

      Diff : constant Integer := Days_Between (Lower_Date  => Value (Lower_Date),
                                               Higher_Date => Value (Higher_Date));
   begin
      Put ("Days between " & Lower_Date & " and " & Higher_Date & " is ");
      Put (Diff, Width => 5);
      Put (" days  
      Put (Comment);
      New_Line;
   end Put_Days_Between;

begin
   Put_Days_Between ("1995-11-21", "1995-11-21", "Identical dates");
   Put_Days_Between ("2019-01-01", "2019-01-02", "Positive span");
   Put_Days_Between ("2019-01-02", "2019-01-01", "Negative span");
   Put_Days_Between ("2019-01-01", "2019-03-01", "Non-leap year");
   Put_Days_Between ("2020-01-01", "2020-03-01", "Leap year");
   Put_Days_Between ("1902-01-01", "1968-12-25", "Past");
   Put_Days_Between ("2090-01-01", "2098-12-25", "Future");
   Put_Days_Between ("1902-01-01", "2098-12-25", "Long span");
end Days_Between_Dates;