Wie kann man mit dem Befehl date herausfinden, welches Datum "Montagwoche 40" sein wird?

11

Wie kann ich mit dem Befehl date so etwas wie "Montagwoche 40" in ein ISO-Datum konvertieren?

Ich spiele mit so etwas:

date --date='monday week 40' +'%Y-%m-%d'

Und das Datum, nach dem ich suche, wäre der 03.10.2011.

Mein Problem ist jedoch, dass diese Datumszeichenfolge nicht gültig ist. Daher benötige ich einen anderen Ansatz, um dieses Problem zu lösen.

/Vielen Dank

Johan
quelle
Über den folgenden Link erfahren Sie, an welchem ​​Tag des Jahres eine nummerierte Woche beginnt. Wochennummerierung (Wikipedia) . Dies erklärt effektiv, warum der 1. Januar dieses Jahres in der ISO-Woche 52 liegt. Die %Vvon 'Benutzer unbekannt' verwendete Formatsequenz gibt die ISO-Wochennummer an .
Peter.O

Antworten:

4

Wirklich hässlich und funktioniert wahrscheinlich nur mit GNU date:

date -d "$( date -d "$( date +'%Y-01-01' ) +40 weeks") -$( date -d "$( date +'%Y-01-01' ) +40 weeks" +'%w' ) days+1 day" +'%Y-%m-%d'

Nur für Ihr Beispiel vom 3. Oktober getestet, kann in einigen anderen Fällen fehlschlagen.


Update : Wenn Sie ein nicht englisches Gebietsschema haben, müssen Sie die Ausgabe ab dem inneren Datum angeben, um zur Arbeit zu gelangen. (Und% F ist nur JJJJ-MM-TT).

date -d "$(date -d "$(date +'%Y-01-01') +40 weeks" +"%F") -$(date -d "$(date +'%Y-01-01') +40 weeks" +%w) days +1 day" +"%F"
Mann bei der Arbeit
quelle
1
Sie haben es versäumt, die Ausgabe vom inneren Datum zu formatieren, damit das äußere sie korrekt verwenden kann.
Johan
@Johan, ich hatte kein Problem mit der Verwendung des Standardformats. Vielleicht ist es länderspezifisch? Ich benutze en_US. Guter Punkt trotzdem.
Manatwork
Für das Datum verwende ich das schwedische Gebietsschema, also gibt es den Unterschied.
Johan
Vielen Dank für die Anpassung des Gebietsschemas. Ich habe ein benutzerdefiniertes Datumsformat und hatte das gleiche Problem. Ich hatte es fast aussortiert, aber jetzt, wo Sie es veröffentlicht haben, werde ich Ihre Optimierung verwenden. es ist besser.
Peter.O
Es war nicht erforderlich, dass dies ein Einzeiler war. Es ist besser, dies in mehrere Zeilen aufzuteilen und temporäre Variablen mit beschreibenden Namen zu verwenden, um die Funktionsweise zu verdeutlichen. Es wird auch davon ausgegangen, dass der 1. Januar jedes Jahr dieselbe Wochennummer hat , was nicht der Fall ist, wie bereits von @ Peter.O angegeben.
Adam Spires
5

Ein alternativer Ansatz:

date --date "+$((40-$(date +%V)))weeks last monday"  +"%F"
  • 40 ist die Woche, nach der Sie suchen
  • Datum +% V gibt die aktuelle Woche zurück (35)
  • 40-35 = 5, das ist die Anzahl der hinzuzufügenden Wochen
  • Von dort aus suchen Sie den letzten Montag
Benutzer unbekannt
quelle
gut, und es funktioniert mit meiner benutzerdefinierten Datumseinstellung.
Peter.O
Dies ist eine clevere Idee, aber sie funktioniert nicht. Wenn heute beispielsweise Montag in Woche 41 ist (dh date +%Vzurückgegeben wird 41), ist der --dateParameterwert +-1weeks last monday, der tatsächlich vor zwei Wochen und nicht vor sieben Tagen liegt.
Adam Spires
Ich bin mir nicht sicher, ob ich Ihre Kritik verstehe. Es ist 2013 in diesem Jahr, daher passt das Beispiel aus der Frage nicht. Was sollte das absolute Datum für die Frage sein und was kehrt mein Ansatz stattdessen zurück (vielleicht: warum)?
Benutzer unbekannt
@AdamSpiers: Mein Kalender wird als Montag, Woche 40, 30. September angezeigt, was mein Algo (heute) ergibt.
Benutzer unbekannt
@userunknown Das liegt daran, dass Sie Ihren Code heute testen. Dies ist ein Dienstag, der nach Montag kommt. Wenn Sie Ihren Code gestern getestet hätten, wäre er kaputt gegangen. Versuchen Sie es mit Laufen, um es deutlicher zu machen date -d 'last monday'. Es wird gestern zurückkehren. Was hätte es wohl gesagt, wenn Sie es gestern betrieben hätten?
Adam Spires
1

OK, hier ist mein Versuch. Es stiehlt Ideen aus den anderen Antworten und versucht, die Logik leichter zu befolgen. Dies basiert auf dem ISO 8601-System, daher ist es nicht korrekt, wenn Sie in Ländern wie den USA oder Kanada leben, sollte aber für diese Länder leicht einstellbar sein.

# sets $week_start to a representation of Monday of the given week
# number formatted via the given format, and similarly sets
# $week_end to Friday of the same week.
get_week_range () {
    week_num="$1" date_format="$2"

    # Most of the world adhere to ISO 8601 which states that weeks begin on Monday
    # and Jan 4th is always in week #1:
    #
    #   http://en.wikipedia.org/wiki/ISO_week_date
    #
    # For other week numbering systems (e.g. USA, Canada), see:
    #
    #   http://en.wikipedia.org/wiki/Seven-day_week#Week_numbering
    day_in_week_1=$( date +'%Y-01-04' )
    day_num_in_week_1=$( date -d $day_in_week_1 +%u ) # 1 is Monday
    days_from_week_1_start=$(( $day_num_in_week_1 - 1 ))
    # This is a Monday:
    start_of_week_1=$( date -d "$day_in_week_1 - $days_from_week_1_start days" +%F )

    week_delta="$(( $week_num - 1 ))"
    # Monday:
    week_start=$( date -d "$start_of_week_1 + $week_delta weeks"          +"$date_format" )
    # Friday:
    week_end=$(   date -d "$start_of_week_1 + $week_delta weeks + 4 days" +"$date_format" )
}
Adam Spires
quelle