Using `date` command to get previous, current and next month
LinuxBashUnixDateLinux Problem Overview
I am using below to get previous, current and the next month under Ubuntu
11.04:
LAST_MONTH=`date +'%m' -d 'last month'`
NEXT_MONTH=`date +'%m' -d 'next month'`
THIS_MONTH=`date +'%m' -d 'now'`
It works well until today, the last day of October, 2012 (2012-10-31)
I get below result as of now:
$ date
Wed Oct 31 15:35:26 PDT 2012
$ date +'%m' -d 'last month'
10
$ date +'%m' -d 'now'
10
$ $ date +'%m' -d 'next month'
12
I suppose the outputs should be 9
,10
,11
respectively.
Don't understand why date
outputs behave like this. What should be a good way to get consistant previous
, current
and next
month instead?
Linux Solutions
Solution 1 - Linux
The problem is that date
takes your request quite literally and tries to use a date of 31st September (being 31st October minus one month) and then because that doesn't exist it moves to the next day which does. The date
documentation (from info date
) has the following advice:
> The fuzz in units can cause problems with relative items. For > example, `2003-07-31 -1 month' might evaluate to 2003-07-01, because > 2003-06-31 is an invalid date. To determine the previous month more > reliably, you can ask for the month before the 15th of the current > month. For example: > > $ date -R > Thu, 31 Jul 2003 13:02:39 -0700 > $ date --date='-1 month' +'Last month was %B?' > Last month was July? > $ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!' > Last month was June!
Solution 2 - Linux
the following will do:
date -d "$(date +%Y-%m-1) -1 month" +%-m
date -d "$(date +%Y-%m-1) 0 month" +%-m
date -d "$(date +%Y-%m-1) 1 month" +%-m
or as you need:
LAST_MONTH=`date -d "$(date +%Y-%m-1) -1 month" +%-m`
NEXT_MONTH=`date -d "$(date +%Y-%m-1) 1 month" +%-m`
THIS_MONTH=`date -d "$(date +%Y-%m-1) 0 month" +%-m`
you asked for output like 9,10,11, so I used the %-m
%m
(without -) will produce output like 09,... (leading zero)
this also works for more/less than 12 months:
date -d "$(date +%Y-%m-1) -13 month" +%-m
just try
date -d "$(date +%Y-%m-1) -13 month"
to see full result
Solution 3 - Linux
If you happen to be using date in a MacOS environment, try this:
ST1:~ ejf$ date
Mon Feb 20 21:55:48 CST 2017
ST1:~ ejf$ date -v-1m +%m
01
ST1:~ ejf$ date -v+1m +%m
03
Also, I'd rather calculate the previous and next month on the first day of each month, this way you won't have issues with months ending the 30/31 or 28/29 (Feb/Feb leap year)
Solution 4 - Linux
the main problem occur when you don't have date --date option available and you don't have permission to install it, then try below -
Previous month
#cal -3|awk 'NR==1{print toupper(substr($1,1,3))"-"$2}'
DEC-2016
Current month
#cal -3|awk 'NR==1{print toupper(substr($3,1,3))"-"$4}'
JAN-2017
Next month
#cal -3|awk 'NR==1{print toupper(substr($5,1,3))"-"$6}'
FEB-2017
Solution 5 - Linux
Previous month:
date -d "1 month ago" +'%m'
Current month:
date +'%m'
Next month:
date -d "-1 month ago" +'%m'