Kirjautuminen

Haku

Tehtävät

Koodit: QB: Viikonpäivän selvitys

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

Kommentit

Juhko [22.01.2007 16:51:34]

#

Hauska, ehkä tuosta jotain hyötyä on...

Metabolix [29.10.2023 17:53:59]

#

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; "."

Grez [29.10.2023 18:21:56]

#

Alkuperäisen vinkin lähdekin näkyy muuten yhä löytyvän netistä vielä 23 vuoden jälkeenkin:
https://brisray.com/qbasic/qdate.htm

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta