Task: Days between dates
C: #include<stdbool.h>
#include<string.h>
#include<stdio.h>

typedef struct{
    int year, month, day;
}date;

date extractDate(char* str){
    return (date){.year = 1000 * (str[0]-'0') + 100 * (str[1]-'0') + 10 * (str[2]-'0') + (str[3]-'0'), .month = 10*(str[5]-'0') + (str[6]-'0'), .day = 10*(str[8]-'0') + (str[9]-'0')};
}

bool isValidDate(char* str){
    date newDate;
    
    if(strlen(str)!=10 && str[4]!='-' && str[7]!='-'){
        return false;
    }

    newDate = extractDate(str);

    if(newDate.year<=0 || newDate.month<=0 || newDate.day<=0 || newDate.month>12 || (newDate.month==2 && newDate.day>29) || 
      ((newDate.month==1 || newDate.month==3 || newDate.month==5 || newDate.month==7 || newDate.month==8 || newDate.month==10 || newDate.month==12) && newDate.day>31) || 
      newDate.day>30 || (newDate.year%4==0 && newDate.month==2 && newDate.month>28)){
          return false;
      }

    return true;
}

int diffDays(date date1,date date2){
    int days1, days2;
    
    date1.month = (date1.month + 9)%12;
    date1.year = date1.year - date1.month/10;

    date2.month = (date2.month + 9)%12;
    date2.year = date2.year - date2.month/10;

    days1 = 365*date1.year + date1.year/4 - date1.year/100 + date1.year/400 + (date1.month*306 + 5)/10 + ( date1.day - 1 );
    days2 = 365*date2.year + date2.year/4 - date2.year/100 + date2.year/400 + (date2.month*306 + 5)/10 + ( date2.day - 1 );

    return days2 - days1;
}

int main(int argc,char** argv)
{
    if(argc!=3){
        return printf("Usage : %s <yyyy-mm-dd> <yyyy-mm-dd>",argv[0]);
    }

    if(isValidDate(argv[1])&&isValidDate(argv[2]) == false){
        return printf("Dates are invalid.\n");
    }

    printf("Days Difference : %d\n", diffDays(extractDate(argv[1]),extractDate(argv[2])));

    return 0;
}

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;
}