                       TinyDate  -  Datumaritmetik


Med datumaritmetik menar jag att jmfra datum och att rkna med datum och
att omvandla datum p olika form. En form fr datum skulle d vara den van-
liga eller en veckodag eller ett veckonummer eller ett dagnummer i ret eller
en helgdag. Men frst ngra reflektioner.

I mars 92 beskte jag Stonehenge, det mrkliga stenldersmonumentet med
anor frn 3000 f Kr. Jag vill grna tro p Hoyles teorier att det ursprung-
liga Stonehenge var en "datamaskin" med kalenderfunktioner och frutsgelse
av mnfrmrkelser. Sol och mne levererade indata som hngivna prster
lste av mot syftlinjer och lagrade i form av lsa stenar i ngot av de 56
(Aubrey Holes) groparna. Stenarna flyttades sedan rutinmssigt av samma opera-
tivsystem mellan groparna allt eftersom mnen indikerade veckor. S hll man
ordning p sin kalender, dr kanske mnfrmrkelser tillmttes stor religis
betydelse. Men efter ngra hundra r gick kunskapen, dvs PROGRAMMET, frlorad
och fr att frska terstlla funktionen uppgraderade man HRDVARAN genom
att resa de vldiga stenblocken. Det hjlpte inte den gngen.

Idag flyttas inga smstenar mellan groparna i Stonehenge, men midsommar-
dagen gr solen fortfarande upp ungefr ver hlstenen sett frn centrum
och man hller fortfarnade enklast reda p datum med LPANDE rkning.
Jordklotet snurrar fortfarande ca 365,2422 varv fr ett rs omlopp kring
solen, vilket skapat mycket huvudbry bland tidrknare i alla tider. Vrre
kalendrar n vr stkar fortfarande till det i vissa kulturer.

All tidrkning har en STARTPUNKT. (Inte ndvndigtvis Big Bang.) Astronomer-
na rknar tiden i julianska dagtal med decimaler fr h,m,s med startpunkt
lngt fre Stonehenge. Det blir frsts astronomiska tal. DOSet i min PC rk-
nar sekunder sedan 1970! och till 2048. Det blir ocks stora tal. Dock krver
precisionen i de flesta mjukvaruprojekt knappast tidrkning p sekunden nr.

I en bekvm tidrkning NUMRERAS dagarna lpande. I frsta hand tnker jag nu
p PC och DOS. Njer man sig med NUTID och ett litet intervall ryms en hel
LIVSTID i en INTEGER , dvs 2 bytes. Vad sgs om att - hedra ABC80 ? och -
starta 1 jan 1980 och rkna dagtal lpande t o m 2068 ? Det kan aldrig vara
helt fel ty i sjlva verket dljer sig ett dagtal av ngot slag i alla form-
ler fr berkning av veckodag mm.

Ett sdant datum eller dagtal kallar jag TinyDate, eller TD, ty det r s li-
tet i mnga avseenden. Man behver frsts en funktion fr att omvandla system-
datum, TD:= FromSys, eller r,mn,dag till TD, TD:= FromDate(r,Mn,Dag),
och helst den inversa proceduren, ToDate(TD,r,Mn,Dag), fr att omvandla
TD tillbaka till r,mn,dag. D lter sig ven procedurerna valideras.

Har man behov av att rkna med eller testa p datum, har man frmodligen mnga
datum-data lagrade i poster eller records i ngon fil. SJLVA VITSEN R JU D
ATT DATUM LAGRAS I FORM AV DAGTAL (TD) - s gr vl DOS i princip? D kan man
ltt testa igenom en fil p strre eller mindre n visst datum (TD) eller N
dagar fre eller efter givet datum, mm, och sortera p datum ven ver sekel-
skiften. Har man inget behov av att RKNA med datum skall detta ALDRIG lagras
i ngon fil! Men tnk igenom vilken STATISTIK som behvs. r "kunden" intres-
serad av ett visst datum r vi det ocks.

Dagar mellan datum r skillnaden mellan TD. Veckodag blir helt enkelt TD modu-
lo 7 fr villkor som 'aldrig p en sndag'. Har man veckodag kan man rkna ut
veckonummer. TD frenklar ven rkning med helgdagar. Helgdagar behvs inte
bara fr kalendrar utan ven fr berkning av arbetsdagar mellan datum fr
t ex analys av genomloppstider eller fr att bestmma bankdagar.

Visst gr det att gra delar av detta med funktioner som finns inbyggda i div
programsprk. Men de fljer alla amerikansk standard - och endast Sverige sven-
ska veckonummer har - och mndagen, veckans mest vrdelsa dag, inleder veckan
och ges vrdet 0. Man tjnar mera CPU nr man testar igenom filer snabbt n man
frlorar vid in- eller utmatning. Drfr ENVISAS jag med att ge ALLA omvand-
lingar mellan datum som funktioner av TD, som jag menar r en halvsmlt form
mellan olika datumformat.

Lt oss numrera dagarna frn 1 jan 1980 och tnk dig en funktion:

FromDate(1980,1,8) som returnerar 8 (i detta fall) ty 1980,1,1 numreras 1
                                  
                                  
            Ti On To Fr L S M Ti On To Fr  ...
             1  2  3  4  5  6  7  8  9 10 11  ...
                                  
                                 =TD
                                  
      och en procedur:     ToDate(TD,1980,1,8)  som ger tillbaka 1980,1,8

TinyDate modulo 7 ger veckodag, dvs TD mod 7, t ex 7/7 ger rest 0 lika
med mndag, 8/7 ger rest 1 lika med tisdag osv.

ToDate(TD) kan ven anvndas fr att validera manuellt givet datum
ty fr t ex 29 feb 1980 r TD=60 (rkna sjlv!) och

 FromDate(1980,2,30)  ... AJ, AJ, AJ, det blev 30, dvs...
                  
                TD=61
                  
...56 57 58 59 60 61 62 63 ...  och ToDate() ger
                  
           ToDate(61,1980,3,1)  dr datum UT skiljer sig frn datum IN.

Startret 1980 kan i princip kas eller minskas med multipler av 4*7=28 s
lnge som intervallets Start-r inte underskrider 1901 eller Slut-r inte
verskrider 2099. Ty frn 1901 till 2099 r vart fjrde r skottr utan
UNDANTAG s tester av typen jmnt delbar med 100 eller inte jmnt delbar med
400 behvs inte! Det har jag utnyttjat. Den som gitter fr annars ndra koden
senast den 28 feb r 2100. Dock hade vi helgreformer 1939 och 1953 s ett
intervall om max 89 r komplicerar koden om det brjar tidigare n 1953.
I Turbo Pascal kan en Word rymma ren 1924 - 2099. D fr man utst den kom-
plicerade koden om man vill arbeta i frfluten tid. Veckonummer p formen
VV ges av funktionen ToWeek(TD). Sedan 1973 numreras veckan i det r den har
sina flesta dagar.

Helgdagar r inget konstigt bara man kan berkna psken. Fr det finns det
algoritmer. Jag har modifierat en algoritm frn Meeus, "Astronomical for-
mulae for calculators, 1979", till att ge dag i ret fr lngfredagen,
DayGF:= ToGoodFriday(TDinYear). De till psken relaterade helgerna Kristi
Himmelsfrdsdag och Pingst fljer sedan ett bestmt antal dagar efter lng-
fredagen.

Midsommardagen och Alla Helgons dag infaller p viss lrdag - och veckodag var
ltt. vriga helgdagar infaller p fast dag i ret. Nyrsdagen r alltid dag 1.
(r inte detta ett pedagogiskt ppekande ?) Trettondagen dag 6. Juldagen 359
(eller 360 om skottr). Sedan 1953, d vi slapp Marie Bebdelsedag, som flyt-
tade d den infll i pskveckan, r ordningsfljden fr helgdagarna densamma
r frn r. Ordning och reda allts. Proceduren som berknar TD'n fr helg-
dagar har jag kallat InitHolidays(TDinYear).

Arbetsdagar mellan datum r rtt och sltt TD2 minus TD1 minus antal lrdagar
och sndagar minus antal VRIGA ARBETSFRIA dagar (dvs helger som ej infaller
p weekends samt klmdagar). Proceduren InitFreeDays(TDfirst,TDlast) ger TD'n
fr VRIGA ARBETSFRIA dagar i perioden TDfirst - TDlast. Arbetsdagar mellan
datum ges sedan av WorkDays(TD1,TD2). ven semestrar bemstrar man drefter.

Denna fil tnkes ing i fljande arkiv:
TDQBAS10.ZIP = TinyDate.BAS v1.0 med source i MS QBasic 4.5 i DOS5
TDQBSE10.ZIP = TinyDate.BAS v1.0 med source + EXE i MS Quick Basic 4.5
TDCSE10.ZIP  = TinyDate.C   v1.0 med source + EXE i Borland Turbo C 2.0
TDPSE10.ZIP  = TinyDate.PAS v1.0 med source + EXE i Borland Turbo Pascal 5.5
TDCPPS05.ZIP = TinyDate CPP v0.5 med source i Borlands Turbo C++ 1.0

Copyright (C) Egon Bosved, ABC-klubben <7723> , maj 1992

Egon Bosved
Skyttev 52
181 46 Liding
Sweden
tel 08/767 17 81

REM ' /*
// PS
// Jag har programmerat datumrutiner frst p Texas rknedosa TI59 sedan
// i urBasic och i UCSD Pascal, drefter som testprogram allt eftersom jag
// frskt mig p nya sprk.
// DS
REM ' */
