# How to generate a year-quarter date from the command line?

I'm interested in outputting a representation of the current year-quarter, as well as the year-quarter for the previous month.

If today is 2012 January 1st, I'd like to get

2012q1


and

2011q4


as the respective outputs.

-

One (kinda ugly) solution, using BASH arithmetic evaluation and the GNU date command:

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


Note that the %-m prevents date from 0-padding, so this will still work for August and September.

-
Take $(...) instead of the deprecated backticks. They can easily be nested. – user unknown Feb 15 '12 at 4:45 just be curious: why other answers use 4 as divisor. – LiuYan 刘研 Jan 29 '13 at 10:32 @LiuYan刘研: Not sure. There are 3 months in a quarter, so I think 3 is the correct divisor. (Though that confused me at first, too.) – smokris Jan 29 '13 at 15:10 In September %m gives 09 which bash tries to interpret as octal due to the leading 0, so this throws an error that says 09: value too great for base (error token is "09"). This can be fixed by disabling 0-padding by changing %m to %-m. – Matthew Jul 17 '15 at 22:07 Probably, there is no direct solution. You could use awk to avoid so many 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);}'  A perl solution would be cleaner but perl and DateTime are an heavy prerequisite. #!/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"  - Cool. I like the first date/awk line, since it avoids calling (and passing parameters to) date twice. – smokris Feb 15 '12 at 1:49 Split the format with date, calculate with awk, format with printf: date +"%Y %m" | awk '{printf ("%4dq%1d\n",$1, ($2/4)+1)}'  Just date and bash: echo$(date +%Yq)$(($(date +%m)/4+1))

-
The first line outputs 2012q0 which is incorrect. – smokris Feb 15 '12 at 4:25
@smokris: You're right - I picked the wrong line of my tests. – user unknown Feb 15 '12 at 4:41

Use my dateutils:

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


The %q and %Q flags are specific to dateutils, and return the quarter as number or in the form Q<NUMBER>.

-
Very cool. Thanks for the link. – smokris Apr 14 '12 at 1:24
dconv now -f%Y%Q | tr Q q if you really need that Q to be lower cased. (PS: we're packaging this in Fedora with date as the prefix instead of d, so "dateconv".) – mattdm May 28 '15 at 1:36

An alternative, more as a curiosity. If GNU awk is involved, date is not needed:

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

-

All solutions that divide by four fail, for instance November:

% echo $(( 11/4+1 )) 3  The correct math would be: $(( (m-1)/3 +1 ))


And as such, the quarter of current and previous month would be:

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


It's only twelve values to check, really…

% 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 For "All solutions that divide by for fail". You're right! A quarter last for 3 months so the answers should be dividing by 3. – Stephen Quan May 28 '15 at 0:31

Call date to retrieve the current year and month, and do the rest with arithmetic in the 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

-

Year-Quarter for this month

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

-

Basic math for this quarter and last month's quarter:

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


The script uses the following parts:

1. $(unix-cmd) - evaluates a command in shell script 2.$((expr)) - evaluates a mathematical expression
3. remapping 1..12 -> 1..4 uses the following math (m-1)/3+1
4. evaluating the previous month uses modulo math
-