calcul on date
Author Message calcul on date

Hi,

I have to compute the number of days between two dates.
The dates are given with the following format : 981031 for 31st October
1998

So, if the dates are :   981005 and 980929 ,the result should be 6 days.

Is it possible to do it with AWK ( i don't think so).
If not where could i find a C program to do this job.

Many thanks in advance.

Pierre.

Wed, 18 Apr 2001 03:00:00 GMT  calcul on date

Quote:

> Hi,

> I have to compute the number of days between two dates.
> The dates are given with the following format : 981031 for 31st October
> 1998

> So, if the dates are :   981005 and 980929 ,the result should be 6 days.

> Is it possible to do it with AWK ( i don't think so).

Yes, it is possible. AWK (newer versions) can do even fairly advanced
math including trig functions, etc.

However, in order to help, it would be good to know the fromat of the
file. Essentially, all you need to do is to get the two dates into two
variables and perform a suntraction on them. Without knowing the format
of the file though, it is difficult to help. Will the two dates occur in
one line of the file? or on separate lines? If on separate lines, are
there intervening lines between the two date lines? Are the dates in
regular fields or is the file free format? These are the questions that
would need to be answered before anybody here will be able to give you
more concrete help. It is usually best to provide a sample of the data
which you will need to process.

Quote:
> If not where could i find a C program to do this job.

> Many thanks in advance.

> Pierre.

Cesar
--
Please remove the uppercase characters from my e-mail address for the
real thing

Wed, 18 Apr 2001 03:00:00 GMT  calcul on date

Quote:
>Hi,

>I have to compute the number of days between two dates.
>The dates are given with the following format : 981031 for 31st October
>1998

>So, if the dates are :   981005 and 980929 ,the result should be 6 days.

>Is it possible to do it with AWK ( i don't think so).
>If not where could i find a C program to do this job.

Using the strftime function you should be able to do this.
strftime is available in gawk and works like the strftime
function in C.

man gawk
man strftime

Chuck Demas
Needham, Mass.

--
Eat Healthy    |   _ _   | Nothing would be done at all,

Die Anyway     |    v    | That no one could find fault with it.

Wed, 18 Apr 2001 03:00:00 GMT  calcul on date

....

Quote:
>I have to compute the number of days between two dates.
>The dates are given with the following format : 981031 for 31st October
>1998

>So, if the dates are :   981005 and 980929 ,the result should be 6 days.

....

There is a book called "The AWK Programming Language" by the authors of the
language, Alfred V Aho, Brian W Kernighan, Peter J Weinberger (Addison-Wesley
Publishing Company). On page 194 there's an answer to Exercise 3-8 giving a
function to convert dates to serial numbers based on 1 = 1901/01/01.

In case you don't use gawk, here's a variation that returns an error message
upon invalid date argument and handles leap years at centuries.

# ignorant of Julian vs Gregorian dates
# 2-digit years converted to 19YY
# assumes date argument in [Y..]YYMMDD format
function dateserial(date,  md, y, m, d, t) {
split("31 28 31 30 31 30 31 31 30 31 30 31", md)

t = length(date)
d = 0 + substr(date, t - 1, 2)
m = 0 + substr(date, t - 3, 2)
y = ( t <= 6 ? 1900 : 0) + substr(date, 1, t - 4)

md += (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))

if ( !(m in md) )
return sprintf("<invalid month %s in %s>", m, date)

if ( d < 1 || md[m] < d )
return sprintf("<invalid day %s in %s>", d, date)

t = 365 * ( y - 1901 ) + int((y - 1901) / 4) \
- int((y - 1900) / 100) + int((y - 1600) / 400)
while ( --m ) t += md[m] + (m == 2 && ly)
t += d

return t

Quote:
}

Thu, 19 Apr 2001 03:00:00 GMT  calcul on date

Quote:

> Yes, it is possible. AWK (newer versions) can do even fairly advanced
> math including trig functions, etc.

> However, in order to help, it would be good to know the fromat of the
> file. Essentially, all you need to do is to get the two dates into two

> variables and perform a suntraction on them. Without knowing the
> format
> of the file though, it is difficult to help. Will the two dates occur
> in
> one line of the file? or on separate lines? If on separate lines, are
> there intervening lines between the two date lines? Are the dates in
> regular fields or is the file free format? These are the questions
> that
> would need to be answered before anybody here will be able to give you

> more concrete help. It is usually best to provide a sample of the data

> which you will need to process.

Ok then,  here is the format of the file :

xxxxxxxx  981029  980925  981022
yyyyyyyy  981029  980913  981019
zzzzzzzzz   981030  980831  981017
and so on.

I have to know the number of days between today and the date in column 2
(second field)

So after the script i should see

xxxxxxxx  981029  980925  981022    -->  3 days   (30 October + 31
October + 1 November)
yyyyyyyy  981029  980913  981019    -->  3 days   (     idem    )
zzzzzzzzz   981030  980831  981017    -->  2 days   (31 October + 1
November)

Many thanks for your answers.

Pierre.

Thu, 19 Apr 2001 03:00:00 GMT  calcul on date

Quote:

> Yes, it is possible. AWK (newer versions) can do even fairly advanced
> math including trig functions, etc.

> However, in order to help, it would be good to know the fromat of the
> file. Essentially, all you need to do is to get the two dates into two

> variables and perform a suntraction on them. Without knowing the
> format
> of the file though, it is difficult to help. Will the two dates occur
> in
> one line of the file? or on separate lines? If on separate lines, are
> there intervening lines between the two date lines? Are the dates in
> regular fields or is the file free format? These are the questions
> that
> would need to be answered before anybody here will be able to give you

> more concrete help. It is usually best to provide a sample of the data

> which you will need to process.

Ok then,  here is the format of the file :

xxxxxxxx  981029  980925  981022
yyyyyyyy  981029  980913  981019
zzzzzzzzz   981030  980831  981017
and so on.

I have to know the number of days between today and the date in column 2
(second field)

So after the script i should see

xxxxxxxx  981029  980925  981022    -->  3 days   (30 October + 31
October + 1 November)
yyyyyyyy  981029  980913  981019    -->  3 days   (     idem    )
zzzzzzzzz   981030  980831  981017    -->  2 days   (31 October + 1
November)

Many thanks for your answers.
(I use awk and not gawk)

Pierre.

Thu, 19 Apr 2001 03:00:00 GMT  calcul on date

Quote:
(HrlnGrv) writes:
>There is a book called "The AWK Programming Language" by the authors of the
>language, Alfred V Aho, Brian W Kernighan, Peter J Weinberger (Addison-Wesley
>Publishing Company). On page 194 there's an answer to Exercise 3-8 giving a
>function to convert dates to serial numbers based on 1 = 1901/01/01.

I was a bit too trusting of the AWK book. There's a bug in the authors'
solution: they're adding leap years using the expression int((y-1901)/4). For
example, if y == 1904, y - 1901 = 3, 3/4 < 1, so int(3/4) = 0, meaning 1904
wasn't a leap year! Code below corrected.

# ignorant of Julian vs Gregorian dates
# 2-digit years converted to 19YY
# assumes date argument in [Y..]YYMMDD format
function dateserial(date,  md, y, m, d, t) {
split("31 28 31 30 31 30 31 31 30 31 30 31", md)

t = length(date)
d = 0 + substr(date, t - 1, 2)
m = 0 + substr(date, t - 3, 2)
y = ( t <= 6 ? 1900 : 0) + substr(date, 1, t - 4)

md += (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))

if ( !(m in md) )
return sprintf("<invalid month %s in %s>", m, date)

if ( d < 1 || md[m] < d )
return sprintf("<invalid day %s in %s>", d, date)

t = 365 * ( y - 1901 ) + int((y - 1900) / 4) \
- int((y - 1900) / 100) + int((y - 1600) / 400)
while ( --m ) t += md[m] + (m == 2 && ly)
t += d

return t

Quote:
}

Thu, 19 Apr 2001 03:00:00 GMT  calcul on date

Quote:

>(HrlnGrv) writes:

>>There is a book called "The AWK Programming Language" by the authors of the
>>language, Alfred V Aho, Brian W Kernighan, Peter J Weinberger
>(Addison-Wesley
>>Publishing Company). On page 194 there's an answer to Exercise 3-8 giving a
>>function to convert dates to serial numbers based on 1 = 1901/01/01.

>I was a bit too trusting of the AWK book. There's a bug in the authors'
>solution: they're adding leap years using the expression int((y-1901)/4). For
>example, if y == 1904, y - 1901 = 3, 3/4 < 1, so int(3/4) = 0, meaning 1904
>wasn't a leap year! Code below corrected.

Nope - I screwed up my interpretation of my test output, and my example above
is dead wrong - don't adjust n = 365 * years for leap years until after the
leap year has ended, so 1904 shouldn't increment n for the leap year, 1905
should. My original reply is correct, my first follow up wrong. Serves me right
for staying up so late.

Thu, 19 Apr 2001 03:00:00 GMT  calcul on date

Perhaps the fourth time through I'll get it right. I caught two other bugs in
my code. Better you should buy the book, but here's corrected code.

# ignorant of Julian vs Gregorian dates
# 2-digit years converted to 19YY
# assumes date argument in [Y..]YYMMDD format
function dateserial(date,  md, y, m, d, t) {
split("31 28 31 30 31 30 31 31 30 31 30 31", md)

t = length(date)
d = 0 + substr(date, t - 1, 2)
m = 0 + substr(date, t - 3, 2)
y = ( t <= 6 ? 1900 : 0) + substr(date, 1, t - 4)

md += (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))

if ( !(m in md) )
return sprintf("<invalid month %s in %s>", m, date)

if ( d < 1 || md[m] < d )
return sprintf("<invalid day %s in %s>", d, date)

t = 365 * ( y - 1901 ) + int((y - 1901) / 4) \
- int((y - 1901) / 100) + int((y - 1601) / 400)    # FIXED!
while ( --m ) t += md[m]    # FIXED!
t += d

return t

Quote:
}

Thu, 19 Apr 2001 03:00:00 GMT  calcul on date
Hi Pierre,

I seem to have missed a key point of your question. You want to do math
not with plain numbers but with numbers representing dates so my
response was totally inadequate for your question. However, I see that
others have contributed with what appear to be working solutions.

Excuse the mistake,

Cesar
--
Please remove the uppercase characters from my e-mail address for the
real thing

Thu, 19 Apr 2001 03:00:00 GMT  calcul on date

Quote:

> Hi,

> I have to compute the number of days between two dates.
> The dates are given with the following format : 981031 for 31st October
> 1998

> So, if the dates are :   981005 and 980929 ,the result should be 6 days.

> Is it possible to do it with AWK ( i don't think so).
> If not where could i find a C program to do this job.

> Many thanks in advance.

> Pierre.

Suppose the file format is

981005   980929

awk '{  for (k=1;k<3;k++) [
day(k)=\$(k)%100
month(k)=((\$(k)-day(k))%10000)/100
year(k)=(\$(k)-100*month(k)-day(k))/10000

Now, define

dayInMonth(1)=31
dayInMonth(2)=28
dayInMonth(3)=31
...
dayInMonth(12)=31
for (y=0;y<100,y++) {
if (y%4==0) {
dayInYear(y)=366

Quote:
} else {
dayInYear(y)=365
}

And then add up intermediate years,
intermediate months in year(1) and year(2)
beware that if year(1) and year(2) have 366 days then dayInMonth(2) is 29
(use an if)
and intermediate days in month(1) and month(2)
+1

not tested
LMS
free sed/awk book:
ftp://ftp.u-aizu.ac.jp/u-aizu/doc/Tech-Report/1997/97-2-007.ps.gz
ftp://ftp.u-aizu.ac.jp/u-aizu/doc/Tech-Report/1997/97-2-007.tar.gz

Fri, 20 Apr 2001 03:00:00 GMT

 Page 1 of 1 [ 11 post ]

Relevant Pages

Powered by phpBB® Forum Software