Task: Discordian date

C: #include <stdlib.h>
#include <stdio.h>
#include <time.h>
 
#define day_of_week( x ) ((x) == 1 ? "Sweetmorn" :\
                          (x) == 2 ? "Boomtime" :\
                          (x) == 3 ? "Pungenday" :\
                          (x) == 4 ? "Prickle-Prickle" :\
                          "Setting Orange")
 
#define season( x ) ((x) == 0 ? "Chaos" :\
                    (x) == 1 ? "Discord" :\
                    (x) == 2 ? "Confusion" :\
                    (x) == 3 ? "Bureaucracy" :\
                    "The Aftermath")
 
#define date( x ) ((x)%73 == 0 ? 73 : (x)%73)
 
#define leap_year( x ) ((x) % 400 == 0 || (((x) % 4) == 0 && (x) % 100))
 
char * ddate( int y, int d ){
  int dyear = 1166 + y;
  char * result = malloc( 100 * sizeof( char ) );
 
  if( leap_year( y ) ){
    if( d == 60 ){
      sprintf( result, "St. Tib's Day, YOLD %d", dyear );
      return result;
    } else if( d >= 60 ){
      -- d;
    }
  }
 
  sprintf( result, "%s, %s %d, YOLD %d",
           day_of_week(d%5), season(((d%73)==0?d-1:d)/73 ), date( d ), dyear );
 
  return result;
}
 
 
int day_of_year( int y, int m, int d ){
  int month_lengths[ 12 ] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
 
  for( ; m > 1; m -- ){
    d += month_lengths[ m - 2 ];
    if( m == 3 && leap_year( y ) ){
      ++ d;
    }
  }
  return d;
}
 
 
int main( int argc, char * argv[] ){
  time_t now;
  struct tm * now_time;
  int year, doy;
 
  if( argc == 1 ){
    now = time( NULL );
    now_time = localtime( &now );
    year = now_time->tm_year + 1900; doy = now_time->tm_yday + 1;
  } else if( argc == 4 ){
    year = atoi( argv[ 1 ] ); doy = day_of_year( atoi( argv[ 1 ] ), atoi( argv[ 2 ] ), atoi( argv[ 3 ] ) );
  }
 
  char * result = ddate( year, doy );
  puts( result );
  free( result );
 
  return 0;
}










Fortran: program discordianDate
    implicit none
    
    character(32) :: arg
    character(15) :: season,day,holyday
    character(80) :: Output,fmt1,fmt2,fmt3
    character(2) :: dayfix,f1,f2,f3,f4
    integer :: i,j,k,daysofyear,dayofweek,seasonnum,yold,dayofseason,t1,t2,t3
    integer,dimension(8) :: values
    integer, dimension(12) :: daysinmonth
    logical  :: isleapyear, isholyday, Pleapyear
     
    
    call date_and_time(VALUES=values)
    
    daysinmonth = (/ 31,28,31,30,31,30,31,31,30,31,30,31 /)
    isleapyear = .false.
    isholyday = .false.
    
    
    j = iargc()
    do i = 1, iargc()
      call getarg(i, arg)  
      if (j==3) then
        if (i==1) then
          read(arg,'(i2)') values(3)  
        endif
        if (i==2) then
          read(arg,'(i2)') values(2)  
        endif
        if (i==3) then
          read(arg,'(i4)') values(1)  
 
        endif
      endif
      if (j==2) then  
        if (i==1) then
          read(arg,'(i2)') values(3)  
        endif
        if (i==2) then
          read(arg,'(i2)') values(2)  
        endif
      endif
      if (j==1) then 
        read(arg,'(i2)') values(3)  
      endif
    end do
 
    

    yold = values(1) + 1166
    daysofyear = 0
    if (values(2)>1) then 
    do i=1 , values(2)-1 , 1
        daysofyear = daysofyear + daysinmonth(i)
     end do
   end if
    daysofyear = daysofyear + values(3)
    isholyday = .false.
    isleapyear = Pleapyear(yold)
    dayofweek = mod (daysofyear, 5)
    seasonnum = ((daysofyear - 1) / 73) + 1 
    dayofseason = daysofyear - ((seasonnum - 1)  * 73)
    k = mod(dayofseason,10)  
    select case (k)
      case (1)
         dayfix='st'
      case (2)
         dayfix='nd'
      case (3)
         dayfix='rd'
      case default
         dayfix='th'
    end select
    
    if (((dayofseason > 10) .and. (dayofseason < 20)) .eqv. .true.) then
      dayfix = 'th'
    end if
    select case (Seasonnum)
      case (1) 
        season ='Choas'
        f4 = '5'
      case (2) 
        season ='Discord'
        f4 = '7'
      case (3) 
        season ='Confusion'
        f4 = '9'
      case (4) 
        season ='Bureaucracy'
        f4 = '10'
      case (5) 
        season ='The Aftermath'
        f4 = '13'
    end select
    select case (dayofweek)
       case (0) 
         day='Setting Orange'
         f2 = '14'
       case (1) 
         day ='Sweetmorn'
         f2 = '9'
       case (2) 
         day = 'Boomtime'
         f2 = '8'
       case (3) 
         day = 'Pungenday'
         f2 = '9'
       case (4) 
         day = 'Prickle-Prickle'
         f2 = '15'
    end select
    
    select case (dayofseason)
      case (5)
        isholyday = .true.
        select case (seasonnum)
          case (1)
             holyday ='Mungday'
             f1 = '7'
          case (2)
             holyday = 'Mojoday'
             f1 = '7'
          case (3)
            holyday = 'Syaday'
            f1 = '6'
          case (4)
             holyday = 'Zaraday'
             f1 = '7'
          case (5)
            holyday = 'Maladay'
            f1 = '7'
         end select
      Case (50)
        isholyday = .true.
        select case (seasonnum)
          case (1)
            holyday = 'Chaoflux'
            f1 = '8'
          case (2)
            holyday = 'Discoflux'
            f1 = '9'
          case (3)
            holyday = 'Confuflux'
            f1 = '9'
          case (4)
            holyday = 'Bureflux'
            f1 = '8'
          case (5)
            holyday = 'Afflux'
            f1 = '6'
         end select
    end select
    

    
    if (isleapyear .eqv. .true.) then 
      if ((values(2) == 2) .and. (values(3) == 29)) then
         isholyday = .true.
      end if
    end if
    
    f3 = "2"
    if (dayofseason < 10) then
      f3 = "1"
    end if
    fmt1 = "(a,i4)"
    fmt2 = "(A,a" // f1 // ",A,A" // f2 // ",A,I" // f3 // ",A2,A,A" // f4 // ",A,I4)"
    fmt3 = "(A,A" // f2 // ",A,I" // f3 //",A2,A,A" // f4 // ",A,I4)"
    
    if (isholyday .eqv. .true.) then
      if (values(3) == 29) then
         print fmt1,'Celebrate for today is St. Tibbs Day in the YOLD ',yold
       else
         print fmt2, 'Today is ',holyday, ' on ',day,' the ',dayofseason,dayfix,' day of ',season,' in the YOLD ',yold 
       end if
     else   
         print fmt3, 'Today is ',day,' the ',dayofseason,dayfix, ' day of ',season,' in the YOLD ',yold
     end if
    end program discordianDate

    

    function Pleapyear(dloy) result(leaper)
    implicit none
    integer, intent(in) :: dloy
    logical :: leaper
    leaper = .false.
    if (mod((dloy-1166),4) == 0)  then
      leaper = .true.
    end if
    if (mod((dloy-1166),100) == 0) then
        leaper = .false.
        if (mod((dloy-1166),400)==0) then
           leaper = .true.
        end if
    end if 
    end function Pleapyear