I wrote below piece of code to calculate the date after a given date -
date=$DATE_FINAL
declare -a max_month=(0 31 28 31 30 31 30 31 31 30 31 30 31)
eval $(echo $date|sed 's!\(....\)\(..\)\(..\)!year=\1;month=\2;day=\3!')
(( year4=year%4 ))
(( year100=year%100 ))
(( year400=year%400 ))
if [ \( $year4 -eq 0 -a \
$year100 -ne 0 \) -o \
$year400 -eq 0 ]
then
declare -a max_month=(0 31 28 31 30 31 30 31 31 30 31 30 31)
fi
day=$((day+1))
if [ $day -gt ${max_month[$month]} ] >| /wload/baot/home/baoted9/logs_bde27_conversion_1/ataa_display.logs 2>&1
then
day=1
month=$((month+1))
if [ $month -gt 12 ]
then
year=$((year+1))
month=1
fi
fi
if [ $month -eq "08" ] || [ $month -eq "09" ]
then
future_date_final=$(echo $year"$month"$day)
else
future_date_final=$(printf "%4.4d%2.2d%2.2d" $year $month $day)
fi
echo "this is your final business date $future_date_final"
It calculates the date correctly however throws an error at the end of the code as below -
line 79: 08: value too great for base (error token is "08")
It just looks too ugly, not sure how to remove it as otherwise code is working fine, tried redirecting it to a log file still appearing.
Also, I am facing issue with below code for a plain cd command with code highlighted in red -
echo "pset date $Param_date_1"
cd /wload/baot/home/baotasa0/sandboxes_finance/ext_ukba_bde/pset >| /wload/baot/home/baoted9/logs_bde27_conversion_1/at_display.logs 2>&1
sh UKBA_publish.sh UKBA $Param_date_1 3 >| /wload/baot/home/baoted9/logs_bde27_conversion_1/ate_display.logs 2>&1
Error is -
./auto2.sh: line 190: syntax error: unexpected end of file
My opinion is that coding date arithmetic and not using existing tools is foolish and error prone. I cannot tell what system you are on, most systems have perl.
#!/bin/sh
# ago.shl
# usage: ago.shl [number]
# for date [number] days ago,
# ./ago.shl -3
# parm $1 == days in past e.g., yesterday = -1,
# days in future e.g., tomorrow = 1
ago()
{
perl -e ' my $delta = $ARGV[0];
$delta*=86400; # seconds in a day
$delta=time + $delta; # epoch seconds today plus ( or minus) delta
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime($delta);
printf("%04d%02d%02d%02d%02d.%02d\n",
$year+1900, $mon+1, $mday;
' $1
}
# example usage of the function ago
when=$(ago $1)
echo "$when"
exit 0
If you are on Linux I would HIGHLY recommend that you use the date command which is very reliable and actually supports options like yesterday and tomorrow. Skip using the perl above.
The "value too great for base" happens because there is a number with a leading zero, and bash assumes octal, and 8 is too high for an octal number.
It happens with
day=$((day+1))
or later with month .
As always there is an escape from such (mis)feature: a 10# prefix forces a base10=decimal
day=$((10#$day+1))
month=$((10#$month))
Now the leading zero are removed.
---------- Post updated at 11:15 ---------- Previous update was at 10:52 ----------
You certainly want
if [ \( $year4 -eq 0 -a \
$year100 -ne 0 \) -o \
$year400 -eq 0 ]
then
declare -a max_month=(0 31 29 31 30 31 30 31 31)
fi
As Jim said, such calculations are error prone.
perl is safer because it uses the libc routines.
Date, time arithmetic, math
1) gnu date
2) ksh ( version 93, not 88; ksh93 M 93t+ ) printf, e.g:
printf "%(%Y-%m-%d)T\n" "yesterday"
Many more examples ( as of 2017.07 ):
http://blog.fpmurphy.com/2008/10/ksh93-date-manipulation.html
3) date.pl (limited arithmetic, but "date.pl -d '- 1 day'" works)
( http://www.unix.com/tips-tutorials/
239167-general-purpose-date-script.html )
4) dconv et al, e.g. ddiff, dconv, strptime (parsing), etc.
( dateutils: http://www.fresse.org/dateutils/ )
5) tm2tm (, OK in 32-bit; fails to compile in 64-bit)
( http://www.unix.com/shell-programming-scripting/
146216-date-difference-between-freebsd-linux.html#post302463136 )
6) perl custom formatting (with function POSIX::strftime, "perldoc POSIX")
7) date-cpan.pl, cpan perl date
( http://cpansearch.perl.org/src/CWEST/ppt-0.14/src/date/date.jgross )
8) For small changes, say, "yesterday" in bash, ksh
TZ=CST+24 date +%Y%m%d
csh, tcsh
setenv TZ CST+24 ; date +%Y%m%d
9) Check for legal date:
manstat:validata ( http://oldwww.acm.org/perlman/stat/ )
10) Check for legal date:
validate (local perl code)
11) Shell, ksh, date calculations:
www.unix.com/unix-for-dummies-questions-and-answers/4870-days-elapsed-between-2-dates.html
Thanks madeingermany...I tried but the error is still because of line I mentioned in my first post n I am using AIX so most of the commands don't work...I need to do date calculation for an arbitrary date so tz doesn't work for me either
~Ekta