Comment générer une date d'un sortingmestre à partir de la command line?

Je suis intéressé à produire une représentation de l'année-sortingmestre en cours, ainsi que le sortingmestre de l'année pour le mois précédent.

Si aujourd'hui est le 1er janvier 2012, j'aimerais avoir

2012q1 

et

 2011q4 

comme les sorties respectives.

Une solution (un peu laide), en utilisant l'évaluation arithmétique BASH et la command de date 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 )) 

Notez que le %-m empêche la date de 0-padding, donc cela fonctionnera toujours pour Août et Septembre.

Utilisez mes dateutils :

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

Les indicateurs %q et %Q sont spécifiques à dateutils et renvoient le sortingmestre sous la forme numérique ou sous la forme Q<NUMBER> .

Toutes les solutions qui divisent par quatre échouent, par exemple Novembre:

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

Le calcul correct serait:

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

Et comme tel, le sortingmestre du mois en cours et le mois précédent serait:

 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 

Ce n'est que douze valeurs à vérifier, vraiment …

 % 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 

Probablement, il n'y a pas de solution directe.

Vous pourriez utiliser awk pour éviter autant de back-ticks.

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

Une solution perl serait plus propre mais perl et DateTime sont une condition préalable lourde.

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

Divisez le format avec la date, calculez avec awk, formatez avec printf:

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

Juste date et bash:

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

Une alternative, plus comme une curiosité. Si GNU awk est impliqué, la date n'est pas nécessaire:

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

date appel pour récupérer l'année et le mois en cours, et faire le rest avec l'arithmétique dans le 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 

Année-sortingmestre pour ce mois

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

Année-sortingmestre pour le mois précédent

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

Mathématiques de base pour ce sortingmestre et le sortingmestre du dernier mois:

 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 

Le script utilise les parties suivantes:

  1. $ (unix-cmd) – évalue une command dans un script shell
  2. $ ((expr)) – évalue une expression mathématique
  3. remappage 1..12 -> 1..4 utilise les maths suivantes (m-1) / 3 + 1
  4. l'évaluation du mois précédent utilise les mathématiques modulo

Il y a maintenant le format %q pour afficher cette information.

Depuis le journal de sortie coreutils-8.26 du 30 novembre 2016:

Nouvelles fonctionnalités

date accepte maintenant le format% q pour sortir le sortingmestre de l'année.

Et oui ça marche!

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