Rufen Sie das Datum des letzten Tages des letzten Monats in einem Shell-Skript ab


11

Wie erhalte ich das Enddatum des Vormonats basierend auf dem Verarbeitungsdatum?

Beispiele:

  • Verarbeitungsdatum = 15jan2015
  • Voraussichtliches Datum = 31dec2014,

  • Bearbeitungsdatum = 10feb2015
  • Voraussichtliches Datum = 31jan2015

Antworten:


27

Mit GNU date:

$ date +%d%b%Y
16Aug2015
$ date -d "$(date +%Y-%m-01) -1 day" +%d%b%Y
31Jul2015

Einige Shells bieten integrierte Unterstützung für die Datumsmanipulation:

Mit ksh93:

$ printf "%(%d%b%Y)T\n" "1st day, yesterday"
31Jul2015

Mit zsh:

$ zmodload zsh/datetime
$ strftime -s d %Y-%m-01-12 $EPOCHSECONDS
$ strftime -rs d %Y-%m-%d-%H $d
$ strftime %d%b%Y $((d-86400))
31Jul2015

4

Es gibt viele Möglichkeiten , dies zu tun. Hier ist die einfachste, die ich gefunden habe (hier unter der Annahme von GNU date):

$ date -d "-$(date +%d) days"
Fri Jul 31 16:07:23 EDT 2015

1
Die Antwort von @stephane ist klarer, und diese Antwort wird in einigen seltsamen Jahren nicht funktionieren, in denen Tage in der Mitte des Monats übersprungen / hinzugefügt wurden. Ja, das ist passiert. siehe youtube.com/watch?v=-5wpm-gesOY
Strg-Alt-Delor

@richard, die Art und Weise, wie GNU-Datums- Tages- Offsets funktionieren (ein 1-Tages-Offset entspricht nicht einem 24-Stunden-Offset). Ich denke, diese und meine Antwort sollten gleichwertig sein und nur in Zeitzonen fehlschlagen, in denen der letzte Tag eines Monats übersprungen wird ( Wenn dies jemals passieren würde, wäre dies normalerweise auf einer Pazifikinsel der Fall, um auf -12: 00 Offset auf 12:00 Offset (oder -13 auf 11 ...) umzuschalten ...
Stéphane Chazelas

@ Stephenph danke für den Hinweis auf andere Probleme, Zeit ist schwierig. Beachten Sie in Ihrer Lösung, dass für den Fall, dass die Monatsmitte entfernt wird (dies ist geschehen), Tag 30 nicht der 30. Tag ist. Wenn Sie also 30 subtrahieren, gelangen Sie nicht zum letzten Tag des Vormonats. Ich kann nicht sehen, warum dieser nicht funktioniert, wenn es einen ersten Tag im Monat gibt (nicht garantiert). Dies bedeutet jedoch nicht, dass dies der Fall sein wird.
Strg-Alt-Delor

@richard, siehe TZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '1 day ago'. Sie erhalten eine Fehlermeldung, da dort kein 30.12.2011 vorhanden war. Das heißt, der Tagesversatz wurde zur Kalenderzeit vorgenommen. 2011-12-31 minus 31 Tage gibt Ihnen 2011-11-30, weil es 31 von 31 nimmt. Es dauert nicht 31 * 24 * 60 * 60 * 60 Sekunden von der aktuellen Zeit. Vergleichen TZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '24 hour ago'Sie mit dem 29., dh diesmal dem Datum, an dem es 24 * 60 * 60 * 60 Sekunden her war.
Stéphane Chazelas

2

Hier ist eine Version, die unter Mac OS funktioniert und das BSD- dateDienstprogramm verwendet:

date -v1d -v-1d +%d%b%Y

Die Argumente werden der Reihe nach angewendet. Sie können sich vorstellen, dass ein Datum von einem Argument zum nächsten weitergeleitet wird. Beispielsweise:

  • Beginnen Sie mit dem aktuellen Datum ( date) -> 2017-03-06
  • Stellen Sie dieses Datum auf den 1. Tag seines Monats ein ( -v1d) -> 2017-03-01
  • Subtrahieren Sie einen Tag davon ( -v-1d)-> 28.02.2017
  • Formatieren Sie das Datum ( +%d%b%Y) -> 28Feb2017

Sie können eine beliebige Anzahl von Monaten vorwärts oder rückwärts erreichen date -v-1m -v1d -v-1d, indem Sie die gewünschte -1mAnzahl von Monaten rückwärts oder vorwärts ( +1m) ersetzen .

Das ist die generische Antwort. In dieser Frage werden speziell Daten zu einem Startdatum abgefragt. Mit dem Mac OS / BSD-Datumsdienstprogramm können Sie keinen Datenstempel angeben, ab dem Sie beginnen können. Sie können jedoch jedes Datumselement einzeln festlegen:

date -v2015y -v1m -v15d -v1d -v-1d +%d%b%Y -> 31Dez2014


0

Versuchen Sie es mit diesem Code

date -d "-$(date +%d) days  month" +%Y-%m-%d

Das gibt den letzten Tag dieses Monats.
Warren Young
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.