Display previous days dates in ksh

---------- Post updated at 03:42 AM ---------- Previous update was at 03:38 AM ----------

Sorry for a duplicate post, my post at the first place could not appear due to some net issue on my machine. Here is what i posted earlier:

Hi, i am using ksh in Solaris, i wanted to assign today's, yesterday's, and day before yesterday's date ( in mm/dd/YYYY format) to a variable in a script. Presently i am using :

tdate=$( date +"%m/%d/%Y" ) #Today
ydate=$(date +"%m/$(date +"%d" | awk '{ printf ("%02d",($1-1)) }')/%Y") #Yesterday
bydate=$(date +"%m/$(date +"%d" | awk '{ printf ("%02d",($1-2)) }')/%Y") #Day before yesterday

It works fine most of the time until today's date is 1 . Going by above logic, last two day's date would be 0 and -1, which in turn should be 30 and 29 or 31 and 30 based on the month( and a special case for February and leap year ). Presently i am making an exception on those days and making my job manually, but i wish to automate the process all along. Can someone help me to have a more optimized and accurate logic.
Thanks in advance

No need of awk

try this

$ tdate=$( date +"%m/%d/%Y" ) # Today

$ ydate=$( date -d" -1 day" +"%m/%d/%Y" ) # Yesterday OR

$ ydate=$( date --date yesterday  +"%m/%d/%Y" ) # Yesterday

$ dydate=$( date -d" -2 day" +"%m/%d/%Y" ) # Day before yesterday OR

$ dydate=$( date --date="2 days ago" +"%m/%d/%Y" ) # Day before yesterday

$ echo $tdate
12/15/2013

$ echo $ydate
12/14/2013

$ echo $dydate
12/13/2013

Thanks Akshay,
Now i realize how pathetic my approach was :stuck_out_tongue: .

hi,
Problem is similar so tried continuing in the same thread than opening a new one. the problem now is i am trying to calculate time elapsed between two instances, at present i am using below in awk where date command doesn't work:

std=substr($2,4,2) ;                          #start date
end=substr($4,4,2) ;                         #end date
mul=((end-std)-1);                           #no: of full days elapsed in the interval
t1=(3600*substr($3,1,2)+60*substr($3,4,2)+substr($3,7,2)); #total no: of start time seconds
t2=(3600*substr($5,1,2)+60*substr($5,4,2)+substr($5,7,2)); #total no: of end time seconds
if (mul == "-1")                                 #both instances in the same day
t=t2-t1;
else                                               #instances occur in two different days
t=((24*3600)-t1)+(mul*24*3600)+t2;
printf("%02d:%02d:%02d\n",(t/3600),((t/60)%60),t%60);      #time elapsed in HH:MM:YY format

my input file will be like
name1 12/16/2013 10:56:38 12/16/2013 10:59:37 value1
name2 12/16/2013 04:37:41 12/17/2013 11:34:19 value2

and so on(a sequence of such records)

the problem again is the same. If start of the month appears with date 01 the previous day would be 31 or 30 or 28 (or 29 ) and my logic above wont work then.
One way is i hard code such inatances with month values in case statement. But just want to know if there is some better option to deal this ?
Any help will be gratefully welcome :slight_smile:

---------- Post updated 12-18-13 at 01:34 PM ---------- Previous update was 12-17-13 at 05:40 PM ----------

Does any one have any update? Atleast someone reply that there is no other way to do. Please make a reply so that I try some approach of mine.

Try this perl prog:

#!/usr/bin/env perl
use Time::Local;
use POSIX qw(strftime);

while (my $ln = <STDIN>) {
    my ($d, $smt, $sdy, $sy, $sh, $sm, $ss, $emt, $edy, $ey, $eh, $em, $es) = split(/[ \/:]/, $ln);
        my $t = abs(timelocal($es,$em,$eh,$edy,$emt-1,$ey) -
                timelocal($ss,$sm,$sh,$sdy,$smt-1,$sy));

    printf "%02d:%02d:%02d\n", $t / 3600, ($t / 60) % 60, $t % 60;
}

---------- Post updated at 10:38 AM ---------- Previous update was at 10:14 AM ----------

Call it like this

$ ./datediff.pl < infile
00:02:59
30:56:38

Hi.

A group of date-manipulation utilities is available, among them ddiff. Here's how it works with your sample data:

#!/usr/bin/env ksh

# @(#) s1       Demonstrate date arithmetic, differences, ddiff, dateutils.
# See:
# https://github.com/downloads/hroptatyr/dateutils/dateutils-0.2.3.tar.xz

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C ksh ddiff

FILE=${1-data1}

pl " Input data file $FILE:"
cat $FILE

pl " Results, first-second, second-first:"
while :
do
  if read v1 d1 t1 d2 t2 v2
  then
    x1=${d1}T${t1}
    x2=${d2}T${t2}
    db "first date-time of pair, x1 [$x1]"
    db "last  date-time of pair, x2 [$x2]"
  else
    break
  fi
  ddiff $x1 $x2 -f '%d days and %S seconds' -i "%m/%d/%YT%T"
  ddiff $x2 $x1 -f '%d days and %S seconds' -i "%m/%d/%YT%T"
  pe
done < $FILE

exit 0

producing:

$ ./s1

Environment: LC_ALL = POSIX, LANG = POSIX
(Versions displayed with local utility "version")
OS, ker|rel, machine: SunOS, 5.10, i86pc
Distribution        : Solaris 10 10/08 s10x_u6wos_07b X86
bash GNU bash 3.00.16
ksh M-11/16/88i
ddiff 0.2.6

-----
 Input data file data1:
name1 12/16/2013 10:56:38 12/16/2013 10:59:37 value1
name2 12/16/2013 04:37:41 12/17/2013 11:34:19 value2

-----
 Results, first-second, second-first:
0 days and 179 seconds
0 days and -179 seconds

1 days and 24998 seconds
-1 days and -24998 seconds

This was run under ksh (some demo-support scripts use bash).

NAME
     ddiff - Compute durations between dates and times

SYNOPSIS
     ddiff [OPTION]... DATE/TIME [DATE/TIME]...

DESCRIPTION
     ddiff 0.2.6

     Compute duration from DATE/TIME (the reference date/time) to
     the other DATE/TIMEs given and print the result as duration.
     If the other DATE/TIMEs are omitted read them from stdin.

See the git web page noted in the script. One would need to download and compile the codes (written in c) as I have done today in Solaris:

-rwxr-xr-x   1  105904 Dec 22 12:35 ddiff

if this is beyond your skills then use other solutions above.

Best wishes ... cheers, drl