Contributor: BJ™RN FELTEN

{
   Here you have my DayUtil, I'm sure you can use that instead. As a bonus you
get a function that returns the daynumber of Eastern Day a certain year (yes!
it's true! :) plus some other useful(?) related functions.

                           - = * = -
}

unit DayUtil;
{ some useful date&time related functions }
{ PD by Bj”rn Felten @ 2:203/208 -- Nov 1994 }

{$g+} { three shift instructions need this }

interface

function dayNo(Ye,Mo,Da:word): word; {calculate the daynumber 1..366}
function easternDay(Ye:word): word;  {what day Eastern Day is that year}
function getYear:  word; inline($b4/$2a/$cd/$21/$89/$c8);
function getMonth: word; inline($b4/$2a/$cd/$21/$30/$e4/$88/$f0);
function getDay:   word; inline($b4/$2a/$cd/$21/$30/$e4/$88/$d0);
function getDow:   word; inline($b4/$2a/$cd/$21/$30/$e4);
function getHour:  word; inline($b4/$2c/$cd/$21/$30/$e4/$88/$e8);
function getMin:   word; inline($b4/$2c/$cd/$21/$30/$e4/$88/$c8);
function getSec:   word; inline($b4/$2c/$cd/$21/$30/$e4/$88/$f0);
function workDay(Ye,Mo,Da,Wd:word): boolean; {returns true if a working day}


implementation

function dayNo;assembler;
asm
    mov  bx,Ye
    mov  cx,Mo
    dec  cx      (* Month = 0..11 *)
    mov  di,Da

{   if Month>2 then  }
    cmp  cx,1
    jle  @janfeb

{      S := ((Year mod 4) + 3) div 4 + (4 * Month + 23) div 10 - 1  }
    and  bx,3
    add  bx,3
    shr  bx,2
    mov  ax,cx
    inc  ax
    shl  ax,2
    add  ax,23
    cwd
    push cx
    mov  cx,10
    div  cx
    pop  cx
    dec  ax
    add  bx,ax
    jmp  @eif

{   else  }
@janfeb:

{      S := 0;  }
    xor  bx,bx
@eif:

{   DayNo:= 31 * (Month - 1) + Day - S;  }
    mov  ax,cx
    mov  cx,31
    mul  cx
    add  ax,di
    sub  ax,bx
end;

function easternDay;assembler;
{ uses Gauss' Eastern formula to calculate Eastern Day }
{ you're not supposed to understand this... :) }
{ it took me quite some while to convert the "formula" from }
{ the look up tables, that I found in my encyclopaedia, into }
{ pure, working assembler, so enjoy... }
asm
    mov  ax,Ye
    cmp  ax,99
    jg   @noadd
    cmp  ax,80
    jg   @not2000
    add  ax,100
@not2000:
    add  ax,1900
@noadd:
    mov  bx,ax
    cwd
    mov  cx,19
    div  cx
    mov  ax,dx
    mul  cx
    add  ax,24
    mov  cx,30
    div  cx
    mov  si,dx
    mov  ax,bx
    and  ax,3
    shl  ax,1
    mov  di,ax
    mov  ax,bx
    cwd
    mov  cx,7
    div  cx
    mov  ax,dx
    shl  ax,2
    add  di,ax
    mov  ax,si
    shl  ax,1
    add  ax,si
    shl  ax,1
    add  ax,5
    add  ax,di
    cwd
    div  cx
    add  dx,si
    add  dx,81
    and  bx,3
    jne  @no29
    inc  dx
@no29:
    mov  ax,dx
end;


(*
   (In other countries than Sweden you may have other holidays
   than we have here. But you'll probably recognize Ascension Day,
   Whit-Monday and the other holidays below, so it shouldn't
   be that difficult to work out your own, country specific,
   modifications to get the workDay function working properly...)

   F”r svenska f”rh†llanden g„ller f”ljande betr„ffande helgdagar:

       Sun:=(WeekDay='S') or   {S”ndag}
      (ThisDate='01 Jan') or   {Ny†rsdagen}
      (ThisDate='06 Jan') or   {Trettondedagen}
      (ThisDate='01 May') or   {1:sta maj}
      (ThisDate='25 Dec') or   {Juldagen}
      (ThisDate='26 Dec');     {Annandag jul}

       EFri:=EasternDay-2;     {L†ngfredag}
       EMon:=EFri+3;           {Annandag p†sk}
       ADay:=EMon+38;          {Kristi himmelsf„rdsdag}
       WMon:=ADay+11;          {Annandag pingst}
*)

function workDay;
var dn,ed:word;
begin
  dn:=dayNo(Ye,Mo,Da); ed:=easternDay(Ye);
  workDay:=not
       ((Wd= 0) or(Wd= 6)  or   {S”ndag eller L”rdag}
       ((Da= 1)and(Mo= 1)) or   {Ny†rsdagen}
       ((Da= 6)and(Mo= 1)) or   {Trettondedagen}
       ((Da= 1)and(Mo= 5)) or   {1:sta maj}
       ((Da=25)and(Mo=12)) or   {Juldagen}
       ((Da=26)and(Mo=12)) or   {Annandag jul}
        (dn=ed- 2)         or   {L†ngfredag}
        (dn=ed+ 1)         or   {Annandag p†sk}
        (dn=ed+39)         or   {Kristi himmelsf„rdsdag}
        (dn=ed+50))             {Annandag pingst}
end;

end.