Date arithmetic in Unix shell scripts

By : ggasp
Source: Stackoverflow.com
Question!

I need to do date arithmetic in Unix shell scripts that I use to control the execution of third party programs.

I'm using a function to increment a day and another to decrement:

IncrementaDia(){
echo $1 | awk '
BEGIN {
diasDelMes[1] = 31
diasDelMes[2] = 28
diasDelMes[3] = 31
diasDelMes[4] = 30
diasDelMes[5] = 31
diasDelMes[6] = 30
diasDelMes[7] = 31
diasDelMes[8] = 31
diasDelMes[9] = 30
diasDelMes[10] = 31
diasDelMes[11] = 30
diasDelMes[12] = 31
}
{
anio=substr($1,1,4)
mes=substr($1,5,2)
dia=substr($1,7,2)

if((anio % 4 == 0 && anio % 100 != 0) || anio % 400 == 0)
{
diasDelMes[2] = 29;
}

if( dia == diasDelMes[int(mes)] ) {
if( int(mes) == 12 ) {
anio = anio + 1
mes = 1
dia = 1
} else {
mes = mes + 1
dia = 1
}
} else {
dia = dia + 1
}
}
END {
printf("%04d%02d%02d", anio, mes, dia)
}
'
}

if [ $# -eq 1 ]; then
tomorrow=$1
else
today=$(date +"%Y%m%d")
tomorrow=$(IncrementaDia $hoy)
fi

but now I need to do more complex arithmetic.

What it's the best and more compatible way to do this?

By : ggasp


Answers

This works for me:

TZ=GMT+6;
export TZ
mes=`date --date='2 days ago' '+%m'`
dia=`date --date='2 days ago' '+%d'`
anio=`date --date='2 days ago' '+%Y'`
hora=`date --date='2 days ago' '+%H'`


Assuming you have GNU date, like so:

date --date='1 days ago' '+%a'

And similar phrases.

By : abyx


For BSD / OS X compatibility, you can also use the date utility with -j and -v to do date math. See the FreeBSD manpage for date. You could combine the previous Linux answers with this answer which might provide you with sufficient compatibility.

On BSD, as Linux, running date will give you the current date:

$ date
Wed 12 Nov 2014 13:36:00 AEDT

Now with BSD's date you can do math with -v, for example listing tomorrow's date (+1d is plus one day):

$ date -v +1d
Thu 13 Nov 2014 13:36:34 AEDT

You can use an existing date as the base, and optionally specify the parse format using strftime, and make sure you use -j so you don't change your system date:

$ date -j -f "%a %b %d %H:%M:%S %Y %z" "Sat Aug 09 13:37:14 2014 +1100"
Sat  9 Aug 2014 12:37:14 AEST

And you can use this as the base of date calculations:

$ date -v +1d -f "%a %b %d %H:%M:%S %Y %z" "Sat Aug 09 13:37:14 2014 +1100"
Sun 10 Aug 2014 12:37:14 AEST

Note that -v implies -j.

Multiple adjustments can be provided sequentially:

$ date -v +1m -v -1w
Fri  5 Dec 2014 13:40:07 AEDT

See the manpage for more details.

By : sj26


This video can help you solving your question :)
By: admin