Antworten:
Eine (etwas hässliche) Lösung, bei der die arithmetische Auswertung von BASH und der date
Befehl GNU verwendet werden :
echo $(date +%Y)q$(( ($(date +%-m)-1)/3+1 ))
echo $(date -d "-1 month" +%Y)q$(( ($(date -d "-1 month" +%-m)-1)/3+1 ))
Beachten Sie, dass die %-m
verhindert , dass date
von 0-Polster, so dass diese nach wie vor für August und September wird funktionieren.
%m
gibt es an, 09
welche Bash aufgrund der führenden 0 versucht, als oktal zu interpretieren, was einen Fehler auslöst, der besagt 09: value too great for base (error token is "09")
. Dies kann behoben werden, indem das 0-Auffüllen durch Ändern %m
auf deaktiviert wird %-m
.
Benutze meine Dateutils :
dconv 2012-01-01 -f '%Y%Q'
=>
2012Q1
Die Flags %q
und %Q
sind spezifisch für dateutils und geben das Quartal als Zahl oder in Form zurück Q<NUMBER>
.
dconv now -f%Y%Q | tr Q q
wenn Sie wirklich brauchen, dass das Q niedriger ist. (PS: Wir verpacken dies in Fedora mit date
als Präfix anstelle von d
, also " dateconv
".)
Alle Lösungen, die durch vier geteilt werden, schlagen fehl, zum Beispiel im November:
% echo $(( 11/4+1 ))
3
Die richtige Mathematik wäre:
$(( (m-1)/3 +1 ))
Und als solches wäre das Quartal des laufenden und des Vormonats:
echo curr ${y}q$(((m-1)/3+1))
if [ $m = 1 ]; then
echo prev $((y-1))q4
else
echo prev ${y}q$(((m-2)/3+1))
fi
Es sind nur zwölf Werte zu überprüfen, wirklich ...
% for m in {1..12}; do echo $m Q$(((m-1)/3+1)); done
1 Q1
2 Q1
3 Q1
4 Q2
5 Q2
6 Q2
7 Q3
8 Q3
9 Q3
10 Q4
11 Q4
12 Q4
Wahrscheinlich gibt es keine direkte Lösung.
Sie könnten awk
so viele Back-Ticks vermeiden.
date +"%Y %m" | awk '{q=int($2/4)+1; printf("%sq%s\n", $1, q);}'
date +"%Y %m" | awk '{q=int($2/4);y=$1;if (q==0){q=4;y=y-1;}; printf("%sq%s\n", y, q);}'
Eine perl
Lösung wäre aber sauberer perl
und DateTime
eine große Voraussetzung.
#!/usr/bin/perl
use DateTime;
my $today = DateTime->now;
print "today: " . $today->year . "q" . $today->quarter . "\n";
my $ago = DateTime->now->subtract( months=> 4);
print "some time ago: " . $ago->year . "q" . $ago->quarter . "\n"
date
zweimalige Aufrufen (und Übergeben von Parametern) vermeidet .
Teilen Sie das Format mit Datum, berechnen Sie mit awk, formatieren Sie mit printf:
date +"%Y %m" | awk '{printf ("%4dq%1d\n", $1, ($2/4)+1)}'
Nur Date und Bash:
echo $(date +%Yq)$(($(date +%m)/4+1))
2012q0
was falsch ist.
Eine Alternative, eher als Kuriosität. Wenn GNU awk
beteiligt ist, date
wird nicht benötigt:
awk 'BEGIN{print strftime("%Y")"q"int((strftime("%-m")-1)/3)+1}'
Rufen Sie date
an, um das aktuelle Jahr und den aktuellen Monat abzurufen, und erledigen Sie den Rest mit der Arithmetik in der Shell.
set $(date '+%Y %m');
this_quarter=${1}q$(($2 / 4 + 1))
if [ $2 -eq 1 ]; then
last_month_quarter=$(($1 - 1))q4
else
last_month_quarter=${1}q$((($2 - 1) / 4 + 1))
fi
Grundlegende Mathematik für dieses Quartal und das Quartal des letzten Monats:
y1=$(date +%Y)
m1=$(date +%m)
q1=$(( (m1 - 1) / 3 + 1))
y2=$(( y1 - (m1 == 1) ))
m2=$(( (m1 + 10) % 12 + 1 ))
q2=$(( (m2 - 1) / 3 + 1 ))
echo This Quarter: $((y1))q$q1
echo Last Month Quarter: $((y2))q$q2
Das Skript verwendet die folgenden Teile:
Es gibt jetzt das %q
Format, um diese Informationen anzuzeigen.
Aus dem Release-Protokoll von coreutils-8.26 vom 30. November 2016:
Neue Funktionen
...
Datum akzeptiert jetzt das% q-Format, um das Quartal des Jahres auszugeben.
Und ja es funktioniert!
$ date "+%q"
4
$ date "+%Yq%q"
2016q4
Wenn Sie das 13-Wochen- Geschäftsquartal möchten , das auf dem ISO-Wochenkalender basiert, funktioniert das neue praktische% q leider nicht. Hier ist eine Version der dateless-Lösung von @ manatwork mit awk / strftime.
awk 'BEGIN{$x=int((strftime("%V")-1)/13)+1;print strftime("%G")"q"($x>4?4:$x)}'
Das letzte kleine ternäre Bit behandelt die ISO-Schaltwochenjahre, in denen das letzte Quartal 14 Wochen umfasst.