Adding days to a date
- From: "randyhyde@xxxxxxxxxxxxx" <randyhyde@xxxxxxxxxxxxx>
- Date: Tue, 26 Jun 2007 06:50:15 -0700
Here's a short routine that will add some number of days to a date.
The date.daterec data structure takes the following form:
namespace date; @fast;
type
daterec:
union
record
day :uns8;
month :uns8;
year :uns16;
endrecord;
date :dword;
endunion;
end date;
Here is date.addDays:
// addDays-
//
// This function adds the specified number of days to
// the date passed by reference.
procedure date.addDays
(
days: uns32;
var theDate:date.daterec
);
@nodisplay;
@noframe;
var
dt :date.daterec;
begin addDays;
push( ebp );
mov( esp, ebp );
sub( _vars_, esp );
push( eax );
push( ebx );
mov( theDate, ebx );
mov( [ebx], eax );
mov( eax, dt.date );
// Optimization: most of the time, the sum of the days plus
// the specified date falls within the current month. A quick
// check for this allows for a *very* fast date computation,
// so it's worth making this check because the situation is
// so common.
//
// Note: the following assumes that the dt.day value is in
// the L.O. byte of the daterec structure.
movzx( al, eax );
add( days, eax );
cmp( eax, 28 );
ja fullDateArith;
// Okay, we've got the special case here.
// First, verify that the original date
// was valid.
pushd( [ebx] );
call date._validate;
// Now store away the new day value:
mov( al, (type date.daterec [ebx]).day );
pop( ebx );
pop( eax );
leave();
ret( _parms_ );
fullDateArith:
// Okay, if the sum of the days parameter plus theDate might
not
// leave us in the same month, then we're going to do this the
// slow way -- we'll convert the date to a Julian day number,
// add in the days value, then convert the result back to a
// Gregorian date:
pushd( [ebx] );
call date._toJulian; // Also checks validity of date.
add( days, eax );
date.fromJulian( eax, theDate );
pop( ebx );
pop( eax );
leave();
ret( _parms_ );
end addDays;
As the comments note, there is a quick optimization for the case that
the sum of the days plus the current date.day value is less than or
equal to 28 (meaning the sum produces a result within the current
month). If the sum falls outside this range, this function converts
the date to a Julian Day number, adds in the days, and then converts
the result back to a daterec data structure. Because toJulian and
fromJulian are relatively complex calculations (involving DIV), we
want to avoid calling these routines for common cases.
The date.toJulian and date.fromJulian functions were given in a
previous post.
hLater,
Randy Hyde
.
- Prev by Date: Re: Some Date and Time Routines
- Next by Date: Re: Some Date and Time Routines
- Previous by thread: Some Date and Time Routines
- Next by thread: Betov, Randy, Hutcho ... enough is enough yeah?
- Index(es):
Relevant Pages
|