Come generare una data di trimestre dalla riga di comando?


10

Sono interessato a presentare una rappresentazione del trimestre corrente, nonché del trimestre dell'anno precedente.

Se oggi è il 1 ° gennaio 2012, mi piacerebbe ottenere

2012q1

e

2011q4

come le rispettive uscite.

Risposte:


10

Una (piuttosto brutta) soluzione, usando la valutazione aritmetica di BASH e il datecomando GNU :

echo $(date +%Y)q$(( ($(date +%-m)-1)/3+1 ))
echo $(date -d "-1 month" +%Y)q$(( ($(date -d "-1 month" +%-m)-1)/3+1 ))

Tieni presente che %-mimpedisce lo date0-padding, quindi funzionerà comunque per agosto e settembre.


2
Prendi $ (...) invece dei backtick deprecati. Possono essere facilmente nidificati.
utente sconosciuto il

1
siate curiosi: perché altre risposte usano 4 come divisore.
LiuYan 刘 研

2
@LiuYan 刘 研: Non sono sicuro. Ci sono 3 mesi in un quarto, quindi penso che 3 sia il divisore corretto. (Anche se all'inizio mi ha confuso.)
smokris,

A settembre %m09quale bash tenta di interpretare come ottale a causa dello 0 iniziale, quindi questo genera un errore che dice 09: value too great for base (error token is "09"). Questo può essere risolto disabilitando 0-padding cambiando %min %-m.
Matteo,

5

Usa le mie date :

dconv 2012-01-01 -f '%Y%Q'
=>
  2012Q1

I flag %qe %Qsono specifici di dateutils e restituiscono il trimestre come numero o nel modulo Q<NUMBER>.


dconv now -f%Y%Q | tr Q qse hai davvero bisogno che Q sia in maiuscolo. (PS: stiamo confezionando questo in Fedora con datecome prefisso anziché d, quindi " dateconv".)
mattdm

5

Tutte le soluzioni che si dividono per quattro falliscono, ad esempio novembre:

% echo $(( 11/4+1 ))
3

La matematica corretta sarebbe:

$(( (m-1)/3 +1 ))

E come tale, il trimestre del mese corrente e precedente sarebbe:

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

Sono solo dodici i valori da controllare, davvero ...

% 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

1
+1 per "Tutte le soluzioni che si dividono per fallimento". Hai ragione! Un quarto dura 3 mesi, quindi le risposte dovrebbero dividere per 3.
Stephen Quan,

4

Probabilmente, non esiste una soluzione diretta.

Potresti usare awkper evitare così tante zecche.

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);}'

Una perlsoluzione potrebbe essere più pulito ma perle DateTimesono un presupposto pesante.

#!/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"

Freddo. Mi piace la prima riga data / awk, poiché evita di chiamare (e passare parametri) datedue volte.
smokris,

4

Dividi il formato con la data, calcola con awk, formatta con printf:

date +"%Y %m" | awk '{printf ("%4dq%1d\n", $1, ($2/4)+1)}'

Basta uscire e bash:

echo $(date +%Yq)$(($(date +%m)/4+1))

2012q0Viene emessa la prima riga errata.
smokris,

@smokris: hai ragione - ho scelto la linea sbagliata dei miei test.
utente sconosciuto il

4

Un'alternativa, più come una curiosità. Se GNU awkè coinvolto, datenon è necessario:

awk 'BEGIN{print strftime("%Y")"q"int((strftime("%-m")-1)/3)+1}'

3

Chiama dateper recuperare l'anno e il mese attuali e fai il resto con l'aritmetica nella 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

2

Anno-trimestre per questo mese

date +"%Yq$(expr $(expr $(date +%m) - 1) / 3 + 1)"

Anno-trimestre per il mese scorso

date +"%Yq$(expr $(expr $(date -d '-1 month' +%m) - 1) / 3 + 1)"

2

Matematica di base per questo trimestre e il trimestre del mese scorso:

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

Lo script utilizza le seguenti parti:

  1. $ (unix-cmd) - valuta un comando nello script della shell
  2. $ ((expr)) - valuta un'espressione matematica
  3. la rimappatura 1..12 -> 1..4 utilizza la seguente matematica (m-1) / 3 + 1
  4. la valutazione del mese precedente utilizza modulo matematica

2

Ora c'è il %q formato per mostrare queste informazioni.

Dal registro di rilascio coreutils-8.26 del 30 novembre 2016:

Nuove funzionalità
... la
data ora accetta il formato% q per l'output del trimestre dell'anno.

E sì, funziona!

$ date "+%q"
4
$ date "+%Yq%q"
2016q4

0

Se vuoi il trimestre fiscale di 13 settimane basato sul calendario delle settimane ISO, il nuovo utile% q non funzionerà, purtroppo. Ecco una versione della soluzione dateless di @ manatwork con awk / strftime.

awk 'BEGIN{$x=int((strftime("%V")-1)/13)+1;print strftime("%G")"q"($x>4?4:$x)}'

L'ultima piccola punta ternaria gestisce gli anni bisestili della settimana ISO in cui l'ultimo trimestre ha 14 settimane.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.