#!/bin/bash # Weekday # Author: Perette Barella # @(#) $Id$ function get_nth_day_of_month { [ $# -lt 4 ] && return 1 typeset weeknum="$1" number="$1" weekday="$2" monthname="$3" year="$4" [ "$number" = "last" ] && number=5 typeset -i day offset bump result month days case "$weekday" in 0|[nN]|[sS]un*|7) day=0 ;; 1|[mM]|[mM]on*) day=1 ;; 2|[tT]|[tT]ue*) day=2 ;; 3|[wW]|[wW]ed*) day=3 ;; 4|[rR]|[Tt]hu*) day=4 ;; 5|[fF]|[fF]ri*) day=5 ;; 6|[sS]|[sS]at*) day=6 ;; *) exit 1 esac case "$monthname" in 1|01|[jJ]an*) month=1; days=31 ;; 2|02|[fF]eb*) month=2; days=28 ;; 3|03|[mM]ar*) month=3; days=31 ;; 4|04|[aA]pr*) month=4; days=30 ;; 5|05|[mM]ay*) month=5; days=31 ;; 6|06|[jJ]un*) month=6; days=30 ;; 7|07|[jJ]ul*|[jJ]ly) month=7; days=31 ;; 8|08|[aA]ug*) month=8; days=31 ;; 9|09|[sS]ep*) month=9; days=30 ;; 10|[oO]ct*) month=10; days=31 ;; 11|[nN]ov*) month=11; days=30 ;; 12|[dD]ec*) month=12; days=31 ;; esac set $(cal $month $year | tail +3 | head -1) offset=$# let "result = day + 1 + ((number - 1) * 7) + offset" let "bump = 7 - offset" [ $day -ge $bump ] && let "result = result - 7" if [ $result -gt $days ] then [ "$weeknum" = "last" ] || return 1 let "result = result - 7" fi printf "%s\n" "$result" return 0 } function test_ok { typeset result expected="$1" shift 1 result=$(get_nth_day_of_month "$@") || printf "%s\n" "Failed: get_nth_day_of_month returned failure." [ $result -eq $expected ] || printf "%s\n" "Failed: get_nth_day_of_month $* returned $result, expected $expected." } if [ "$1" = "RUN_UNIT_TEST_NOW" ] then # Month starting in middle test_ok 1 1 fri 11 2002 test_ok 2 1 sat 11 2002 test_ok 3 1 sun 11 2002 test_ok 4 1 mon 11 2002 test_ok 7 1 thu 11 2002 test_ok 7 1 thu 11 2002 test_ok 8 2 fri 11 2002 test_ok 14 2 thu 11 2002 test_ok 25 4 mon 11 2002 test_ok 28 last thur 11 2002 test_ok 29 last fri 11 2002 # Month starting on Sunday test_ok 1 1 sun 12 2002 test_ok 4 1 wed 12 2002 test_ok 7 1 sat 12 2002 test_ok 15 3 sun 12 2002 test_ok 18 3 wed 12 2002 test_ok 21 3 sat 12 2002 # Month starting on Saturday test_ok 1 1 sat 06 2002 test_ok 2 1 sun 06 2002 test_ok 5 1 wed 06 2002 test_ok 7 1 fri 06 2002 test_ok 25 4 tue 06 2002 test_ok 29 5 sat 06 2002 test_ok 30 5 sun 06 2002 get_nth_day_of_month 1 fri 11 && printf "%s\n" "Failure: get_nth_day_of_month: success with 3 arguments." else if ! get_nth_day_of_month "$@" then arg0=$(basename $0) printf "%s\n" "$arg0: Invalid arguments." 1>&2 printf "%s\n" "Usage: $arg0 " 1>&2 printf "%s\n" "For example, $arg0 4 mon 11 2002 returns the fourth Monday of November, 2002." exit 1 fi fi exit 0 # # Checked out: 12:48:46 11/20/02 # Last modified: 12:48:45 11/20/02 # SCCS/VCS Id: 1.1 #