Kirjoittaja: Antti Laaksonen
Kirjoitettu: 01.02.2002 – 29.10.2023
Tagit: matematiikka, koodi näytille, vinkki
Näpsäkkä tapa selvittää tietyn päivämäärän viikonpäivä. Tämä löytyi alunperin Internetistä, mutta olen suomentanut ja parannellut sitä. Koodi toimii vuoden 1800 maaliskuusta aina vuoden 2199 loppuun saakka.
' Alkuperäinen koodi: Ray Thomas ' Funktio laskee viikonpäivän. ' 0 = sunnuntai, 1 = maanantai, ..., 6 = lauantai. FUNCTION Viikonpaiva(BYVAL Vuosi AS INTEGER, BYVAL Kuukausi AS INTEGER, BYVAL Paiva AS INTEGER) DIM Vuosisata AS INTEGER DIM Taikaluku AS INTEGER IF Kuukausi < 3 THEN Kuukausi = Kuukausi + 12 Vuosi = Vuosi - 1 END IF Vuosisata = Vuosi \ 100 Vuosi = Vuosi MOD 100 Kuukausi = FIX((Kuukausi + 1) * 2.61) SELECT CASE Vuosisata CASE 18: Vuosisata = 2 CASE 19: Vuosisata = 0 CASE 20: Vuosisata = 6 CASE 21: Vuosisata = 4 END SELECT Taikaluku = Vuosisata + Vuosi + Kuukausi + Paiva + (Vuosi \ 4) Viikonpaiva = Taikaluku MOD 7 END FUNCTION DIM Paivamaara AS STRING DIM Paiva AS INTEGER, Kuukausi AS INTEGER, Vuosi AS INTEGER DIM Paivat(7) AS STRING Paivat(0) = "sunnuntai" Paivat(1) = "maanantai" Paivat(2) = "tiistai" Paivat(3) = "keskiviikko" Paivat(4) = "torstai" Paivat(5) = "perjantai" Paivat(6) = "lauantai" DO PRINT "Kirjoita päivä muodossa PP.KK.VVVV (esim. 02.02.2002)." PRINT "Lopeta tyhjällä rivillä." INPUT Paivamaara IF LEN(Paivamaara) <> 10 OR MID$(Paivamaara, 3, 1) <> "." OR MID$(Paivamaara, 6, 1) <> "." THEN EXIT DO Paiva = VAL(LEFT$(Paivamaara, 2)) Kuukausi = VAL(MID$(Paivamaara, 4, 2)) Vuosi = VAL(RIGHT$(Paivamaara, 4)) PRINT "Päivä on "; Paivat(Viikonpaiva(Vuosi, Kuukausi, Paiva)) LOOP
Hauska, ehkä tuosta jotain hyötyä on...
Kun muutetaan alkuperäisen vinkin SELECT-lause vielä kaavaksi, saadaan lyhennettyä funktiota ja saadaan se toimimaan vielä laajemmalla alueella vuosilukuja.
' Funktio laskee viikonpäivän. ' 0 = sunnuntai, 1 = maanantai, ..., 6 = lauantai. FUNCTION Viikonpaiva(BYVAL Vuosi AS INTEGER, BYVAL Kuukausi AS INTEGER, BYVAL Paiva AS INTEGER) IF Kuukausi < 3 THEN Kuukausi = Kuukausi + 12 Vuosi = Vuosi - 1 END IF ' Päivä huomioidaan suoraan. ' Kuukausi huomioidaan kertoimella, joka pyöristyy oikein vuoden aikana. ' Vuosiluvun viimeiset numerot huomioidaan, vuodessa on 1 päivä yli viikon. ' Vuoden jako neljällä tuottaa lisäpäivän tavallisille karkausvuosille. ' Viimeinen osa käsittelee karkausvuoden poikkeukset 100 ja 400 vuoden välein. Viikonpaiva = (Paiva + FIX((Kuukausi + 1) * 2.61) + (Vuosi MOD 100) + ((Vuosi MOD 100) \ 4) + (2 * (3 - ((Vuosi \ 100) MOD 4)))) MOD 7 END FUNCTION
Kommentoin koodiin myös, mihin toiminta perustuu: Vuosilukua koskevilla osilla saadaan laskettua kustakin vuodesta maaliskuun ensimmäinen päivä huomioiden myös karkausvuosien vaikutuksen. Karkauspäivä on tällöin vuoden viimeinen päivä, joten se ei vaadi muuta lisäkäsittelyä. Kuukausissa päästään eteenpäin sopivalla kertoimella. Päivän numero lisätään sellaisenaan.
Funktio voidaan helposti silmukalla testata ja todeta toimivaksi.
DIM Paiva AS INTEGER, Kuukausi AS INTEGER, Vuosi AS INTEGER DIM OikeaViikonpaiva AS INTEGER, Tulos AS INTEGER DIM Oikeat AS LONG, Virheet AS LONG ' Gregoriaaninen kalenteri otettiin käyttöön 15.10.1582. ' Takautuvasti ajatellen 1.1.1582 olisi ollut perjantai. OikeaViikonpaiva = 5 PRINT "Aloitetaan päivästä 1.1.1582." FOR Vuosi = 1582 TO 9999 FOR Kuukausi = 1 TO 12 FOR Paiva = 1 TO 31 IF Paiva > 30 AND (Kuukausi = 4 OR Kuukausi = 6 OR Kuukausi = 9 OR Kuukausi = 11) THEN EXIT FOR IF Paiva > 29 AND Kuukausi = 2 AND NOT (Vuosi MOD 4 <> 0 OR (Vuosi MOD 100 = 0 AND Vuosi MOD 400 <> 0)) THEN EXIT FOR IF Paiva > 28 AND Kuukausi = 2 AND (Vuosi MOD 4 <> 0 OR (Vuosi MOD 100 = 0 AND Vuosi MOD 400 <> 0)) THEN EXIT FOR Tulos = Viikonpaiva(Vuosi, Kuukausi, Paiva) IF Tulos <> OikeaViikonpaiva THEN PRINT Paiva; "."; Kuukausi; "."; Vuosi; " on "; OikeaViikonpaiva; ", funktion tulos "; Tulos; "." Virheet = Virheet + 1 ELSE IF Paiva = 1 AND Kuukausi = 1 THEN PRINT "Vuosi "; Vuosi; " alkaa viikonpäivällä "; Tulos Oikeat = Oikeat + 1 END IF OikeaViikonpaiva = (OikeaViikonpaiva + 1) MOD 7 NEXT Paiva NEXT Kuukausi NEXT Vuosi PRINT "Näissä vuosissa oikeita viikonpäiviä oli "; Oikeat; " ja virheitä "; Virheet; "."
Alkuperäisen vinkin lähdekin näkyy muuten yhä löytyvän netistä vielä 23 vuoden jälkeenkin:
https://brisray.com/qbasic/qdate.htm