Extra Blog

Letzter Tag eines Monats ermitteln.

Kunden und Ihre Anforderungen..... wer kennt das nicht?

Da will ein Kunde statistische Auswertungen am letzten Tag des Monats durchgeführt haben. Und weil der Datenstamm leider keinen Rückschluss auf dessen Erstellung / Änderung zulässt, kommt man nicht umhin den letzten Tag des Monats zur Ausführung zu ermitteln. Die crontab gibt diesbezüglich ja nichts her.

 Wann ist denn der letzte Tag eines Monats? Der letzte Tag eines Monats ist: Wenn der Folgetag der 1. ist. Also date +%d == 01; oder der Monat des Folgetag != von heute ist.

Mancher wird schon ahnen, wohin die Reise geht. Es gibt aber mehrere Lösungen für unterschiedliche uniode Plattformen oder eben auch eine für Windows anwendbare Lösungen.

Die wohl einfachste Lösung in einem shell Script wäre:

[ "01" != `date --date=tomorrow +%d` ] && exit 0 # An allen anderen Tagen Script beenden; echo "Today is the last day of the month";

Allerdings wird das auf HPUX und ggf. Solaris nicht funktionieren. Denn nur das unter Linux verfügbare date kennt die Option --date.

Über den Vergleich zum Monat wie folgt.

[ `date +%m` == `date --date=tomorrow +%m` ] && exit 0 # An allen anderen Tagen Script beenden; echo "Today is the last day of the month";

Besser, erfordert jedoch eine Perlinstallation (welche auf Unioden Systemen i.d.R. vorhanden ist). Der Perl Aufruf lässt sich ggf. auch in bat Scripten einbinden und auswerten, womit sich der Perlaufruf auch für Windows nutzen lässt.

[ "01" != `perl -e 'use POSIX;print strftime "%d\n",localtime time+86400;'` ] && exit 0 # An allen anderen Tagen Script beenden; echo "Today is the last day of the month";


Noch keine Kommentare

  • Berthold Fischer  
    Könnte mich fast darüber ärgern, wie simpel das eigentlich ist.

    Hab bisher immer die Kunden davon überzeugt, dass es besser wäre solche Scripte am 01. um 00:00 starten zu lassen.
    Mit Leichtigkeit lässt sich das dann auch für den Versand von Erinnerungsmails 2 Tage zum Monatsende usw. anpassen.

    Vielen Dank
    #1
  • ThorstenS  
    Mit date, cal und awk kann ich auch einfach zwischen normalen Werktagen, Freitagen und dem letzten Freitag im Monat unterscheiden. Das benutze ich um das richtige Backupband für amanda rauszusuchen:

    TODAY=$(/bin/date -d "-$OFFSET days" +%e)
    # weekday
    TODAYWD=$(/bin/date -d "-$OFFSET days" +%a)
    # number of weekday
    TODAYNR=$(/bin/date -d "-$OFFSET days" +%u)
    # echo -e "Heute ist der: ${TODAY}. also ein $TODAYWD, der $TODAYNR Tag in der Woche"

    if [ "$TODAYNR" -eq "5" ]
    then
    # echo -n "=> Freitag erkannt - "
    if [ `/usr/bin/cal | /usr/bin/awk 'NF >= 6 {print $6}' | tail -1` -eq $TODAY ]
    then
    # echo -e "letzter Freitag"
    DUMPTYPE=MonthlySet1
    TAPE=$(tail -1 /etc/amanda/$DUMPTYPE/tapelist | awk '{ print $2}')
    else
    # echo -e "Normaler Freitag"
    DUMPTYPE=WeeklySet1
    TAPE=$(tail -1 /etc/amanda/$DUMPTYPE/tapelist | awk '{ print $2}')
    fi
    else
    # echo -n "=> Wochentag erkannt - "
    DUMPTYPE="DailySet1"
    TAPE=$(tail -1 /etc/amanda/$DUMPTYPE/tapelist | awk '{ print $2}')
    fi

    (Die massigen br-Tags hat S9Y eingefügt...)
    #2
    • Matthias  
      Hi, das bekommst Du so aber auf der HPUX und auch auf dem Mac nicht zum laufen.

      Auch hier würde ich das ganze in ein Perl Script packen und z.B. die Tapes in eine hash Referenz packen.
      Der letzte Freitag eines Monats liegt max. 7 Tage also 604800 Sekunden zurück.
      Heisst also, /bin/date -d "+7 days" +%d < 8!
      Lässt sich wunderbar mit dem Timestamp rechnen.
      Auch liese sich Dein shell Script schöner gestalten.


      Ich habe es nur mal grob überflogen:


      DUMPTYPE=DailySet1
      if [ `/bin/date +%d` -eq "5" ]
      then
      # echo -n "=> Freitag erkannt - "
      # In 7 Tagen ist wieder Freitag. Und war der 7. eines Monats der Freitag, war der letzte Tag des Vormonats ebenfalls ein Freitag.
      # echo -e "Normaler Freitag und falls nicht, wird gleich überschrieben ;-)"
      DUMPTYPE=WeeklySet1
      if [ `/bin/date -d "+7 days" +%d` -lt 8 ]
      then
      # echo -e "letzter Freitag"
      DUMPTYPE=MonthlySet1
      fi
      fi
      # Diese Zuweisung muss man nur einmal formulieren. Reicht zum Schluss.

      TAPE=$(tail -1 /etc/amanda/$DUMPTYPE/tapelist | awk '{ print $2}')


      -> Bitte selbständig nochmals prüfen ob das mit der 2. If Abfrage auch passt. Habs nicht geprüft sollte aber so passen.
      Aber eben mit dem Nachteil, das klappt auf der HPUX und MACOS erstmal nicht.
      Weil date dort die option -d nicht kennt.

      Ohne Kommentar und in einer MAC sowie HPUX funktionalen Version:



      DUMPTYPE=DailySet1
      if [ `/bin/date +%d` -eq "5" ]
      then
      DUMPTYPE="WeeklySet1"
      if [ `perl -e 'use POSIX;print strftime "%d\n",localtime time+604800;'` -lt 8 ]
      then
      DUMPTYPE="MonthlySet1"
      fi
      fi
      TAPE=$(tail -1 /etc/amanda/$DUMPTYPE/tapelist | awk '{ print $2}')

Die Kommentarfunktion wurde vom Besitzer dieses Blogs in diesem Eintrag deaktiviert.