comp:ftagebash
no way to compare when less than two revisions
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
— | comp:ftagebash [2014-08-12 1702] (aktuell) – angelegt werner | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== Bash: Feiertage ====== | ||
+ | |||
+ | Der folgende Code ist entstanden, als es galt, eine Feiertagsprüfung in Bash (wahlweise AWK) umzusetzen. Also habe ich mal die Feiertage für Sachsen und Sachsen-Anhalt berechnen lassen... Ist nicht schnell, aber funktioniert. | ||
+ | |||
+ | Historisch gesehen, habe ich das zum ersten Mal Ende der 80er Jahre in Pascal geschrieben, | ||
+ | |||
+ | <file bash / | ||
+ | #!/bin/bash | ||
+ | |||
+ | # Funktionssammlung fuer Kalenderzwecke | ||
+ | # checkJahr $JAHR | ||
+ | # checkMonat $MONAT | ||
+ | # checkTag $TAG $MONAT $JAHR | ||
+ | # is_Leapyear $JAHR | ||
+ | # cal_days_in_month $MONAT $JAHR | ||
+ | # getKarfreitag $JAHR | ||
+ | # getOstersonntag $JAHR | ||
+ | # getOstermontag $JAHR | ||
+ | # getHimmelfahrt $JAHR | ||
+ | # getAdvent1 $JAHR | ||
+ | # getAdvent2 $JAHR | ||
+ | # getAdvent3 $JAHR | ||
+ | # getAdvent4 $JAHR | ||
+ | # getWochentag $TAG $MONAT $JAHR | ||
+ | # istFeiertag $TAG $MONAT $JAHR | ||
+ | |||
+ | EWIGERKALENDER=' | ||
+ | [ -f " | ||
+ | |||
+ | # testet, ob das angegebene Jahr eine vierstellige Zahl und mindestens 1683 ist | ||
+ | # Param1: Jahreszahl | ||
+ | # Rückgabe: 1 bei Fehler, 0 wenn OK | ||
+ | # | ||
+ | checkJahr() { | ||
+ | # integer, > 1683 | ||
+ | TESTJAHR=${1: | ||
+ | VERSJ=$(echo " | ||
+ | [ -z " | ||
+ | if [[ $TESTJAHR =~ ^[0-9]+$ ]] && [ $TESTJAHR -gt 1683 ]; then | ||
+ | echo 0 | ||
+ | return 0 | ||
+ | else | ||
+ | echo 1 | ||
+ | return 1 | ||
+ | fi | ||
+ | } # checkJahr | ||
+ | |||
+ | # testet, ob der angegebene Jahr Monat im Bereich 1 bis 12 liegt | ||
+ | # Param1: Monatsnummer | ||
+ | # Rückgabe: 1 bei Fehler, 0 wenn OK | ||
+ | # | ||
+ | checkMonat() { | ||
+ | # integer, Bereich 1..12 | ||
+ | TESTMONAT=${1: | ||
+ | if [[ $TESTMONAT =~ ^[0-9]+$ ]] && [ $TESTMONAT -ge 1 -a $TESTMONAT -le 12 ]; then | ||
+ | echo 0 | ||
+ | return 0 | ||
+ | else | ||
+ | echo 1 | ||
+ | return 1 | ||
+ | fi | ||
+ | } # checkMonat | ||
+ | |||
+ | # teste, ob es sich um ein Schaltjahr handelt | ||
+ | # Param1: Jahreszahl | ||
+ | # Rückgabe: Text 0 bei Fehler, Text 1 wenn OK | ||
+ | # | ||
+ | is_Leapyear() { | ||
+ | RETVAL=9 | ||
+ | TESTJAHR=${1: | ||
+ | JAHR_OK=$(checkJahr $TESTJAHR) | ||
+ | if [ " | ||
+ | echo $RETVAL | ||
+ | return $RETVAL | ||
+ | fi | ||
+ | if [ $(($TESTJAHR % 100)) -ne 0 -a $(($TESTJAHR % 4)) -eq 0 ]; then | ||
+ | RETVAL=1 | ||
+ | elif [ $(($TESTJAHR % 400)) == 0 ]; then | ||
+ | RETVAL=1 | ||
+ | else | ||
+ | RETVAL=0 | ||
+ | fi | ||
+ | echo $RETVAL | ||
+ | return $RETVAL | ||
+ | } # is_Leapyear | ||
+ | |||
+ | # Anzahl Tage im Kalendermonat | ||
+ | # Param1: Monatszahl, siehe checkMonat | ||
+ | # Param2: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: eine Zahl im Bereich 28..31, je nachdem :-) | ||
+ | # im Fehlerfall eine 1 (Errorlevel wird gesetzt) | ||
+ | cal_days_in_month() { | ||
+ | TESTMONAT=${1: | ||
+ | TESTJAHR=${2: | ||
+ | JAHR_OK=$(checkJahr $TESTJAHR) | ||
+ | MONAT_OK=$(checkMonat $TESTMONAT) | ||
+ | if [ " | ||
+ | echo 1 | ||
+ | return 1 | ||
+ | fi | ||
+ | case $TESTMONAT in | ||
+ | 1|3|5|7|8|10|12) | ||
+ | 4|6|9|11) | ||
+ | 2) if [ is_Leapyear $TESTJAHR ]; then | ||
+ | RETVAL=29 | ||
+ | else | ||
+ | RETVAL=28 | ||
+ | fi | ||
+ | ;; | ||
+ | esac | ||
+ | echo $RETVAL | ||
+ | } # cal_days_in_month | ||
+ | |||
+ | # testet, ob ein Tag im erlaubten Bereich (Monatslänge) ist | ||
+ | # Param1: Tageszahl | ||
+ | # Param2: Monatszahl, siehe checkMonat | ||
+ | # Param3: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Tageszahl (Param1), wenn Tag möglich ist | ||
+ | # sonst letzter Tag des Monats | ||
+ | # $? = 0, wenn Tag möglich ist, 1 sonst | ||
+ | checkTag() { | ||
+ | TESTTAG=${1: | ||
+ | TESTMONAT=${2: | ||
+ | TESTJAHR=${3: | ||
+ | [ " | ||
+ | [ " | ||
+ | # echo " | ||
+ | TAG_OK=$(echo $TESTTAG | tr -d [0-9]) | ||
+ | # if [[ $TESTTAG =~ ^[0-9]+$ ]] && [[ $TESTTAG -lt 1 ]]; then | ||
+ | let " | ||
+ | if [ -z " | ||
+ | : | ||
+ | else | ||
+ | echo 1 | ||
+ | return 1 | ||
+ | fi | ||
+ | JAHR_OK=$(checkJahr $TESTJAHR) | ||
+ | if [ " | ||
+ | echo 2 | ||
+ | return 1 | ||
+ | fi | ||
+ | MON_OK=$(checkMonat $TESTMONAT) | ||
+ | if [ " | ||
+ | echo 3 | ||
+ | return 1 | ||
+ | fi | ||
+ | MAXTAGE=$(cal_days_in_month $TESTMONAT $TESTJAHR) | ||
+ | if [ $MAXTAGE -ge $TESTTAG ]; then | ||
+ | echo $TESTTAG | ||
+ | return 0 | ||
+ | else | ||
+ | echo $MAXTAGE | ||
+ | return 1 | ||
+ | fi | ||
+ | } # checkTag | ||
+ | |||
+ | # berechnet das Osterdatum nach Gauss | ||
+ | # Param1: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Ostersonntag im Format YYYY-MM-DD | ||
+ | getOstersonntag() { | ||
+ | TESTJAHR=${1: | ||
+ | [ $TESTJAHR -eq 0 ] && TESTJAHR=$(date +%Y) | ||
+ | G=$(expr $TESTJAHR % 19 + 1) | ||
+ | C=$(expr $TESTJAHR / 100 + 1) | ||
+ | X=$(expr \( $C / 4 - 4 \) \* 3) | ||
+ | Z=$(expr \( $C \* 8 + 5 \) / 25 - 5) | ||
+ | D=$(expr $TESTJAHR \* 5 / 4 - $X - 10) | ||
+ | E=$(expr \( $G \* 11 + $Z - $X + 20 \) % 30) | ||
+ | [ $E -lt 0 ] && E=$(expr $E + 30) | ||
+ | [ $E -eq 25 -a $G -gt 11 -o $E -eq 24 ] && E=$(expr $E + 1) | ||
+ | TAG=$(expr 44 - $E) | ||
+ | [ $TAG -lt 21 ] && TAG=$(expr $TAG + 30) | ||
+ | TAG=$(expr $TAG + 7 - \( $D + $TAG \) % 7) | ||
+ | if [ $TAG -gt 31 ] ; then | ||
+ | | ||
+ | MON=4 | ||
+ | else | ||
+ | MON=3 | ||
+ | fi | ||
+ | echo " | ||
+ | } # getOstersonntag | ||
+ | |||
+ | # berechnet das Datum des 1. Advent | ||
+ | # Param1: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Datum im Format YYYY-MM-DD | ||
+ | getAdvent1() { | ||
+ | DJHR=$1 | ||
+ | # numerisch? | ||
+ | TSTJHR=$(echo " | ||
+ | [ -z " | ||
+ | # lang genug? | ||
+ | [ " | ||
+ | DMON=11 | ||
+ | DTAG=27 | ||
+ | ZIELWOTAG=' | ||
+ | ISTWOTAG=$(getWochentag $DTAG $DMON $DJHR) | ||
+ | while [ " | ||
+ | STICHSEK=$(date -d " | ||
+ | let " | ||
+ | DTAG=$(date -d " | ||
+ | DMON=$(date -d " | ||
+ | ISTWOTAG=$(getWochentag $DTAG $DMON $DJHR) | ||
+ | done | ||
+ | date -d " | ||
+ | } # getAdvent1 | ||
+ | |||
+ | # berechnet das Datum des 2. Advent | ||
+ | # Param1: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Datum im Format YYYY-MM-DD | ||
+ | getAdvent2() { | ||
+ | DJHR=$1 | ||
+ | # numerisch? | ||
+ | TSTJHR=$(echo " | ||
+ | [ -z " | ||
+ | # lang genug? | ||
+ | [ " | ||
+ | # Basis: 1. Advent | ||
+ | ADV1=$(getAdvent1 $DJHR) | ||
+ | SEKDAT=$(date -d " | ||
+ | # plus eine Woche | ||
+ | DIFF=$((7 * 86400)) | ||
+ | let " | ||
+ | date -d " | ||
+ | } # getAdvent2 | ||
+ | |||
+ | # berechnet das Datum des 3. Advent | ||
+ | # Param1: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Datum im Format YYYY-MM-DD | ||
+ | getAdvent3() { | ||
+ | DJHR=$1 | ||
+ | # numerisch? | ||
+ | TSTJHR=$(echo " | ||
+ | [ -z " | ||
+ | # lang genug? | ||
+ | [ " | ||
+ | # Basis: 1. Advent | ||
+ | ADV1=$(getAdvent1 $DJHR) | ||
+ | SEKDAT=$(date -d " | ||
+ | # plus zwei Wochen | ||
+ | DIFF=$((2 * 7 * 86400)) | ||
+ | let " | ||
+ | date -d " | ||
+ | } # getAdvent3 | ||
+ | |||
+ | # berechnet das Datum des 4. Advent | ||
+ | # Param1: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Datum im Format YYYY-MM-DD | ||
+ | getAdvent4() { | ||
+ | DJHR=$1 | ||
+ | # numerisch? | ||
+ | TSTJHR=$(echo " | ||
+ | [ -z " | ||
+ | # lang genug? | ||
+ | [ " | ||
+ | # Basis: 1. Advent | ||
+ | ADV1=$(getAdvent1 $DJHR) | ||
+ | SEKDAT=$(date -d " | ||
+ | # plus drei Wochen | ||
+ | DIFF=$((3 * 7 * 86400)) | ||
+ | let " | ||
+ | date -d " | ||
+ | } # getAdvent4 | ||
+ | |||
+ | # berechnet das Datum des Buß- und Bettags | ||
+ | # Param1: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Datum im Format YYYY-MM-DD | ||
+ | getBusstag() { | ||
+ | DJHR=$1 | ||
+ | # numerisch? | ||
+ | TSTJHR=$(echo " | ||
+ | [ -z " | ||
+ | # lang genug? | ||
+ | [ " | ||
+ | # Basis: 1. Advent | ||
+ | ADV1=$(getAdvent1 $DJHR) | ||
+ | SEKDAT=$(date -d " | ||
+ | # minus 10 tage | ||
+ | DIFF=$((10 * 86400)) | ||
+ | let " | ||
+ | date -d " | ||
+ | } # getBusstag | ||
+ | |||
+ | # berechnet das Datum des Ostermontags | ||
+ | # Param1: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Datum im Format YYYY-MM-DD | ||
+ | getOstermontag() { | ||
+ | ODAT=$1 | ||
+ | [ -z " | ||
+ | # in Sekunden umwandeln | ||
+ | OSONN=$(date -d " | ||
+ | # Differenz hinzu | ||
+ | OMONTAG=$(($OSONN + 86400)) | ||
+ | # im Format YYYY-MM-DD ausgeben | ||
+ | date -d " | ||
+ | } # getOstermontag | ||
+ | |||
+ | # berechnet das Datum des Karfreitags | ||
+ | # Param1: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Datum im Format YYYY-MM-DD | ||
+ | getKarfreitag() { | ||
+ | ODAT=$1 | ||
+ | [ -z " | ||
+ | # in Sekunden umwandeln | ||
+ | OSONN=$(date -d " | ||
+ | # Differenz hinzu | ||
+ | SEKDIFF=$((2 * 86400)) | ||
+ | KARFTAG=$(($OSONN + $SEKDIFF)) | ||
+ | # im Format YYYY-MM-DD ausgeben | ||
+ | date -d " | ||
+ | } # getKarfreitag | ||
+ | |||
+ | # berechnet das Datum des Pfingstsonntags | ||
+ | # Param1: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Datum im Format YYYY-MM-DD | ||
+ | getPfingstsonntag() { | ||
+ | ODAT=$1 | ||
+ | [ -z " | ||
+ | # in Sekunden umwandeln | ||
+ | OSONN=$(date -d " | ||
+ | # Differenz hinzu | ||
+ | SEKDIFF=$((49 * 86400)) | ||
+ | PFSONN=$(($OSONN + $SEKDIFF)) | ||
+ | # im Format YYYY-MM-DD ausgeben | ||
+ | date -d " | ||
+ | } # getPfingstsonntag | ||
+ | |||
+ | # berechnet das Datum des Pfingstmontags | ||
+ | # Param1: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Datum im Format YYYY-MM-DD | ||
+ | getPfingstmontag() { | ||
+ | ODAT=$1 | ||
+ | [ -z " | ||
+ | # in Sekunden umwandeln | ||
+ | OSONN=$(date -d " | ||
+ | # Differenz hinzu | ||
+ | SEKDIFF=$((50 * 86400)) | ||
+ | PFMON=$(($OSONN + $SEKDIFF)) | ||
+ | # im Format YYYY-MM-DD ausgeben | ||
+ | date -d " | ||
+ | } # getPfingstmontag | ||
+ | |||
+ | # berechnet das Datum von Christi Himmelfahrt | ||
+ | # Param1: Jahreszahl, siehe checkJahr | ||
+ | # Rückgabe: Datum im Format YYYY-MM-DD | ||
+ | getHimmelfahrt() { | ||
+ | ODAT=$1 | ||
+ | [ -z " | ||
+ | # in Sekunden umwandeln | ||
+ | OSONN=$(date -d " | ||
+ | # Differenz hinzu | ||
+ | SEKDIFF=$((39 * 86400)) | ||
+ | HIFAH=$(($OSONN + $SEKDIFF)) | ||
+ | # im Format YYYY-MM-DD ausgeben | ||
+ | date -d " | ||
+ | } # getHimmelfahrt | ||
+ | |||
+ | # prüft, ob es sich beim übergebenen Datum um einen Feiertag handelt | ||
+ | # Param1: Tageszahl, siehe checkTag | ||
+ | # Param2: Monatszahl, siehe checkMonat | ||
+ | # Param3: Jahreszahl, siehe checkJahr | ||
+ | # Param4: Region; ' | ||
+ | # Rückgabe: 1 wenn Feiertag, 0 sonst | ||
+ | # $? wird entsprechend gesetzt | ||
+ | istFeiertag() { | ||
+ | TAG=${1:-0} | ||
+ | MONAT=${2: | ||
+ | JAHR=${3: | ||
+ | INREGION=${4: | ||
+ | RETID=0 | ||
+ | [ " | ||
+ | [ " | ||
+ | [ " | ||
+ | JAHR_OK=$(checkJahr $JAHR) | ||
+ | if [ " | ||
+ | echo 0 | ||
+ | return 1 | ||
+ | fi | ||
+ | [ " | ||
+ | [ " | ||
+ | VGLTAG=$(checkTag $TAG $MONAT $JAHR) | ||
+ | [ $VGLTAG -ne $TAG ] && return 1 | ||
+ | FEIER=0 | ||
+ | if [ $MONAT -eq 12 ]; then | ||
+ | case " | ||
+ | 24|25|26|31) | ||
+ | FEIER=1 | ||
+ | ;; | ||
+ | esac | ||
+ | elif [ $MONAT -eq 10 ]; then | ||
+ | case $TAG in | ||
+ | 3|31) | ||
+ | FEIER=1 | ||
+ | ;; | ||
+ | esac | ||
+ | elif [ $MONAT -eq 5 -a $TAG -eq 1 ]; then | ||
+ | FEIER=1 | ||
+ | elif [ $MONAT -eq 1 -a $TAG -eq 1 ]; then | ||
+ | FEIER=1 | ||
+ | fi | ||
+ | if [ $FEIER -eq 0 ]; then | ||
+ | VGLDAT=" | ||
+ | # jetzt die beweglichen Feiertage | ||
+ | # Lassen wir die Sonntage mal raus ;-) | ||
+ | KFDAT=$(getKarfreitag $JAHR) | ||
+ | # OSDAT=$(getOstersonntag $JAHR) | ||
+ | OMDAT=$(getOstermontag $JAHR) | ||
+ | HFDAT=$(getHimmelfahrt $JAHR) | ||
+ | # PSDAT=$(getPfingstsonntag $JAHR) | ||
+ | PMDAT=$(getPfingstmontag $JAHR) | ||
+ | # A1DAT=$(getAdvent1 $JAHR) | ||
+ | # A2DAT=$(getAdvent2 $JAHR) | ||
+ | # A3DAT=$(getAdvent3 $JAHR) | ||
+ | # A4DAT=$(getAdvent4 $JAHR) | ||
+ | if [ " | ||
+ | FEIER=1 | ||
+ | # elif [ " | ||
+ | # | ||
+ | elif [ " | ||
+ | FEIER=1 | ||
+ | elif [ " | ||
+ | FEIER=1 | ||
+ | # elif [ " | ||
+ | # | ||
+ | elif [ " | ||
+ | FEIER=1 | ||
+ | # elif [ " | ||
+ | # | ||
+ | # elif [ " | ||
+ | # | ||
+ | # elif [ " | ||
+ | # | ||
+ | # elif [ " | ||
+ | # | ||
+ | fi | ||
+ | fi | ||
+ | if [ $FEIER -eq 0 ]; then | ||
+ | # jetzt die bundeslandabhängigen Feiertage | ||
+ | if [ " | ||
+ | BBDAT=$(getBusstag $JAHR) | ||
+ | if [ " | ||
+ | FEIER=1 | ||
+ | fi | ||
+ | else | ||
+ | if [ " | ||
+ | FEIER=1 | ||
+ | fi | ||
+ | fi | ||
+ | fi | ||
+ | echo " | ||
+ | return $FEIER | ||
+ | } # istFeiertag | ||
+ | </ | ||
comp/ftagebash.txt · Zuletzt geändert: 2014-08-12 1702 von werner