`` Written by D. Sureau in Scriptol
`` from a public domain C source.
`` I can't garantee all dates are rights...
`` www.scriptol.net - Public domain.


constant int ISO_CAL = 0

array days      = array(31, 28, 31, 30, 31, 30,  31, 31, 30, 31, 30, 31)
array daynames  = array("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
array months    = array("January", "February", "March", "April",
                        "May", "June", "July", "August",
                        "September", "October", "November", "December")

void usage()
        print "Usage: cal month year"
        print "where: month 1 - 12"
        print "       year 1 - 99 or 1800 - 3000"
        exit(-1)
return

boolean isLeap(int yr)
        boolean x = (yr mod 400) = 0
        boolean y = (yr mod 4) = 0
        boolean z = (yr mod 100) <> 0
return x or (y and z)


int monthsToDays(int month)
return (month * 3057 - 3007) / 100


int yearsToDays(int yr)
return (yr * 365) + (yr / 4) - (yr / 100) + (yr / 400)


int scalarFromYMD(int yr, int mo, int day)
        int scalar
        scalar = day + monthsToDays(mo)
        if mo > 2                          // adjust if past February
                if isLeap(yr)
                        scalar - 1
                else
                        scalar - 2
                /if
        /if
        scalar + yearsToDays(yr - 1)
return scalar


int today()

        int y, m, d
        dict x = localtime()
        y = x["tm_year"]
        m = x["tm_mon"]
        d = x["tm_mday"]

return scalarFromYMD(y + 1900, m + 1, d)



int, int, int scalarToYMD(int scalar)

        int  n = int( ((scalar * 400) / 146097) )

        while yearsToDays(n) < scalar
                n + 1
        /while

        int yr = n
        n = int(scalar - yearsToDays(n - 1))
        if n > 59
                n + 2
                if isLeap(yr)
                        if n >  62
                                n - 1
                        else
                                n - 2
                        /if
                /if
        /if

        int mo = ((n * 100) + 3007) / 3057
        int day = n - monthsToDays(mo)

return yr, mo, day


int main(int argc, array argv)

        int day, firstDay, numdays
        int i, j
        int yr, mo, dy
        int thisMonth, thisYear, thisDay

        thisYear, thisMonth, thisDay = scalarToYMD(today())

        if argc not in 1..3 let usage()

        `` The month, or the month and the year may be given,
        `` the default is the current month at start.

        if argc
        = 3:
                yr = argv[2].toInt()
                mo = argv[1].toInt()
        = 2:
                if argv[1] in ("?", "/h", "-?", "-h", "--help") let usage()
                mo = argv[1].toInt()
                yr, i, j = scalarToYMD(today())
        else
                yr, mo, dy = scalarToYMD(today())
        /if

        if not (mo in 1..12) let usage()

        if yr < 100 let yr + 2000

        if yr not in 1800..3000 let usage()

        for i in 0 .. 2

        if mo < 1
                mo = 12
                yr - 1
        /if

        if mo > 12
                mo = 1
                yr + 1
        /if

        numdays = days[mo - 1]

        `` each 4 years february is 29 days long

        if (mo = 2) and isLeap(yr)
                numdays + 1
        /if

        firstDay = scalarFromYMD(yr, mo - 1, 1) + 1
        firstDay = int(firstDay) mod 7

        print
        for j in 0 .. 6
                echo daynames[j], ' '
        /for

        echo " |--- ", months[mo - 1], ", ", yr, "\n"

        ` adjust starting day in table

        for day in 0 .. firstDay  echo "    "
                day = 0
                while day < numdays
                        day + 1
                        firstDay + 1
                        firstDay = firstDay mod 7
                        if (firstDay = 0) and (day <> 0) print
                        if day < 10 echo ' '
                        if (thisDay = day) and (thisMonth = mo) and (thisYear = yr)
                                echo '[', day, ']'
                        else
                                echo ' ', day, ' '
                        /if
                /while

                mo + 1
                print

        /for

return 0


main($argc, $argv)