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











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;