On Wed, 18 Feb 2009 13:34:02 -0800 (PST), lcaverly wrote in
Post by lcaverlyHi,
Does anyone have a lean user-defined function or batch file to
calculate the difference between two dates? For example;
Paul McCartney was born on June 18, 1942.
As of today, he would be 66 years, 8 months, 0 days old.
66-08-00
I found this algorithm (see in code) and ported it to 4NT. Instead of
using the Unix epoch for date arithmetic, I used a batch file which I
had already lying around, JULIAN.BTM
It's not extensively tested, but your test case works. I tried to make
it 4DOS (7.50 under Win 5.1)compatible, although I don't use that
anymore; however, 4DOS chokes with "Out of environment space" in line
28 (the long one) - left to the discerning reader to fix; this doesn't
happen in 4NT (6.01).
@ECHO OFF
*SETLOCAL
:: Age.BTM Calculate age in years, months, days
:: Author: Michael Bednarek (mb AT mbednarek.com)
:: Input: d1 m1 y1 d2 m2 y2
:: Output: Age in yyyy mm dd
:: Source: http://stackoverflow.com/questions/453208/how-can-i-calculate-the-age-of-a-person-in-year-month-days
:: (replaced FLOOR() with INT() to allow for 4DOS)
:: Needs JULIAN.BTM as a workaround to compute something similar to the Unix "epoch".
FUNCTION tm=`%@EXEC[@CALL JULIAN.BTM %1 %2 %3] %JULIAN`
SET d1=%1
SET m1=%2
SET y1=%3
SET d2=%4
SET m2=%5
SET y2=%6
SET t1=%@EVAL[%y1 * 12 + %m1 - 1]
SET t2=%@EVAL[%y2 * 12 + %m2 - 1]
SET dm=%@EVAL[%t2 - %t1]
IFF %d2 GE %d1 THEN
SET r=%@INT[%@EVAL[%dm / 12]] years, %@EVAL[%dm %% 12] months, %@EVAL[%d2 - %d1] days
ELSE
SET dm=%@EVAL[%dm - 1]
SET t2=%@EVAL[%t2 - 1]
SET r=%@INT[%@EVAL[%dm / 12]] years, %@EVAL[%dm %% 12] months, %@EVAL[%@tm[%d2 %m2 %y2] - %@tm[%d1 %@EVAL[%t2 %% 12 + 1] %@INT[%@EVAL[%t2 / 12]]]] days
ENDIFF
ECHO %r
UNSET d1 m1 y1 d2 m2 y2 r
@*Echo Off
*SETLOCAL
:: JULIAN.BTM Convert Gregorian Date to Julian Day Number
:: Author: Michael Bednarek (mb AT mbednarek.com)
:: Input: dd mm yyyy
:: Output: Echo DOW and JULIAN and return variable JULIAN
:: Method: From a German HP Calculator Manual
:: which says it only works for dates between 1-Mar-1900 and 28-Feb-2100
:: Seems to work longer, though.
:: Parameters are not checked!
:: bias to 1-Jan-4713 BC
Set bias=1720983
:: Prepare
Iff %2 gt 2 Then
Set y2=%3
Set m2=%@Eval[%2 + 1]
Else
Set y2=%@Eval[%3 - 1]
Set m2=%@Eval[%2 + 13]
EndIff
:: This is it
Set JULIAN=%@Eval[%@Int[%@Eval[365.25 * %y2]]+%@Int[%@Eval[30.6001 * %m2]] + %1 + %bias]
Set DOW=%@Word[%@Eval[%JULIAN %% 7],Sun,Mon,Tue,Wed,Thu,Fri,Sat]
:: Clean up
Unset y2 m2 bias
:: Echo only if called from the command line
If %_BATCH eq 1 Echo %JULIAN %DOW
ENDLOCAL JULIAN DOW
Have fun.
--
Michael Bednarek http://mbednarek.com/ "POST NO BILLS"