[Back to DATETIME SWAG index] [Back to Main SWAG index] [Original]
(* Public domain
Author: Marius Ellen, Winsum, Groningen, The Netherlands
Fido 2:282/607.2
After studying several DayOfWeeks i got sick.
None of them worked really correctly and most
had over 15 DIV'/MOD's or * in it.
The Zeller's congruence was the best but the
routine also contains some range errors. Years
are only valid from 1..6300 and its really slow,
so i wrote my own..
About the routines..
routine results valid if year in 0..65536
month in 1..12, and day in 1..28/29/30/31
there is absolute no range checking..
*)
function DayOfWeek(year,month,day:word):word;
{Returns the day of week, 0=Sun..6=Sat}
assembler; {See 1995}
const mtable:array[0..11] of byte=
(0,3, 3,6, 1,4, 6,2, 5,0, 3,5);
asm
{(Y+(Y div 4)-(Y div 100)+(Y div 400)-Adjust)mod 7}
mov ax,year
mov di,ax
xor bx,bx
xor cx,cx
mov si,day
dec si
shr ax,1; adc cl,0 {si+=year div 4}
shr ax,1; adc cl,0
add si,ax
mov bx,25 {si+=year div 100}
xor dx,dx
div bx
sub si,ax
shr ax,1; adc ch,0 {si+=year div 400}
shr ax,1; adc ch,0
add si,ax
add si,di
{if leap-year then decrease days}
mov bx,month
cmp bx,2; ja @Noleap {do not adjust}
and cl,cl; jne @NoLeap {year mod 4=0?}
and dx,dx; jne @IsLeap {year mod 100=0?}
and di,di; je @NoLeap {year=0?}
and ch,ch; jne @Noleap {year mod 400=0?}
@IsLeap:dec si
@Noleap:xor ah,ah
mov al,byte ptr mTable[bx-1]
add ax,si
mov bx,7
xor dx,dx
div bx
xchg ax,dx
end;
function GetDaysInMonth(Month:Byte;Year:Word):Word;
{Returns the total number of days in a month}
assembler;
asm
mov bl,Month
{What about februari?}
cmp bl,2; jne @N
mov ax,Year
shr ax,1; jc @S
shr ax,1; jc @S
{it's a leap-year}
mov cx,25; div cx
and dx,dx; jne @T
{its a century}
and al,3; jne @S
@T: {leap}
mov ax,29; jmp @E
@S: {noleap}
mov ax,28; jmp @E
@N: {Nope, calc moth day's}
mov ax,15
shr bl,1; rcl ax,1
cmp bl,4; jb @E
xor ax,1
@E:
end;
function GetDaysInYear(Year:Word):Word;
{Returns the total number of days in a year}
assembler;
asm
mov ax,2
push ax
push year
call GetDaysInMonth
add ax,(365-28)
end;
[Back to DATETIME SWAG index] [Back to Main SWAG index] [Original]