Get number of days between 2 dates

Gents.
Please can u help.
I would like to calculate the days between two dates.
Example file1 ( previous date)
file1 - Input file

9/29/2010 10195
9/29/2010 1057
2/2/2016 10
2/2/2016 10169
2/2/2016 1057
2/3/2016 10005
2/3/2016 10014  

In file2 I add the actual date using this code.

awk -v date="$(date +"%m/%d/%Y")" '{print $0, date}' file1 > file2

file2

9/29/2010 10195 05/12/2017
9/29/2010 1057 05/12/2017
2/2/2016 10 05/12/2017
2/2/2016 10169 05/12/2017
2/3/2016 10005 05/12/2017
2/3/2016 10014 05/12/2017

then using this code i get the difference ( number of days) for 2 dates

awk -v q='"' 'BEGIN {OFS= ","}{
 c="date -d"q$1q" +%s";c|getline d1;close(c); 
 c="date -d"q$3q" +%s";c|getline d2;close(c);
 printf "%s, %s, %s, %d\n", $1, $2, $3,(d2-d1)/3600/24}' file2  > file3

file3 - Output file, Column 4 is the days between 2 dates.

9/29/2010, 10195, 05/12/2017, 2417
9/29/2010, 1057, 05/12/2017, 2417
2/2/2016, 10, 05/12/2017, 464
2/2/2016, 10169, 05/12/2017, 464
2/3/2016, 10005, 05/12/2017, 463
2/3/2016, 10014, 05/12/2017, 463

It works fine, BUT take a lot time to end.. My input file is a big file and it take very long time to end.

Kindly can you check the code and if it is possible modify it to be faster. Get same output (file3) but more faster.

Appreciate your help

Do the links given at the bottom left under "More UNIX and Linux Forum Topics You Might Find Helpful" help you?

1 Like

Hi RudiC.

Already I look in the More Unix and Linux Forum topics..

But nothing to help..:slight_smile:

No surprise it is taking its time, creating two processes per line for a large file. Try - provided you have a recent bash which you fail to mention -

date -f <(cut -d" " -f1 file2) +"($(printf "%(%s)T\n") - %s)/86400" | bc | paste file2 -
9/29/2010 10195 05/12/2017    2417
9/29/2010 1057 05/12/2017    2417
2/2/2016 10 05/12/2017    465
2/2/2016 10169 05/12/2017    465
2/3/2016 10005 05/12/2017    464
2/3/2016 10014 05/12/2017    464
1 Like

Hi RudiC.

I got :

9/29/2010 10195 05/12/2017    -14880

OK - what would you suggest? Looking at my sample output, comparing it to yours?

1 Like

RudiC
The problem for me is here

date -f <(cut -d" " -f1 file2) +"($(printf "%(%s)T\n") - %s)/86400" | bc | paste file2 -

This value returns 0 for timestamp current date, here shoulbe value = 1494587900..

As I said it needs "a recent bash " - what be your version? Try date instead.

1 Like

RudiC

the bash version i am using is GNU bash, 4.2.37(1) - release (x86_64-pc-linux-gnu)

Hi all,
there is an ancient formula that convert quickly a "gregorian" date (month, day, year) to "julian" date (number of days from January 1 of year 1).

This is the implementation in awk.

File greg_to_jul.awk:

BEGIN {
    limes="31,59,90,120,151,181,212,243,273,304,334,365";
    split(limes, vlim, ",");
    vlim[0]=0;
}

function julian(d,m,a)
{
    bis=(a%4==0 && a%100 != 0 || a%400 == 0);
    da=(a-1)*365+int((a-1)/4)-int((a-1)/100)+int((a-1)/400);
    dm=vlim[m-1]+(m>2 && bis);
    return(da+dm+d);
}

{
 split ($3, v3, "/");
 split ($1, v1, "/");

 printf "%s, %s, %s, %d\n", $1, $2, $3, julian(v3[2], v3[1], v3[3]) - julian(v1[2], v1[1], v1[3]);
}

So, you can obtain your exact results (the second set of they):

awk -f greg_to_jul.awk file2

The user time was 1 ms, versus 60 ms of the previous version.

Regards.

1 Like