Kirjoittaja: Antti Laaksonen
Kirjoitettu: 07.04.2004 – 07.04.2004
Tagit: koodi näytille, vinkki
DOSin käyttäjälle laitenimet, kuten CON (näppäimistö ja näyttö), COM1-4 (sarjaportit) ja LPT1-3 (rinnakkaisportit), ovat varmasti tuttuja. Monien tiedossa myös on, että näitä laitteita voi käyttää aivan tiedoston tavoin esimerkiksi QBasicista käsin. Järjestelmän kelloa edustava CLOCK$ sen sijaan lienee harvemmin käytetty "laite".
CLOCK$:n avulla on mahdollista saada selville ja määrittää järjestelmän aika sadasosasekunnin tarkkuudella. Kellon ymmärtämän merkillisen viestin muoto on seuraava: kuluneet päivät 1.1.1980:n jälkeen (sana), minuutit (tavu), tunnit (tavu), sekunnin sadasosat (tavu), sekunnit (tavu). Yhteensä viesti on siis kuuden tavun pituinen, ja tiedot ovat juuri tässä järjestyksessä.
Seuraava QBasic-ohjelma esittelee CLOCK$:n käyttöä kolmen esimerkin avulla. Mukana on myös aliohjelmat päiväyksen muuttamiseen kuluneiden päivien määräksi ja toisin päin, mikä ei ole aivan yksinkertainen tehtävä. Ohjelma ei valitettavasti tunnu toimivan uusissa Windowseissa, vaan tulee virheilmoitus "Device I/O error"!
DECLARE FUNCTION Paivaykseksi$ (paivat AS INTEGER) DECLARE FUNCTION MJ$ (L AS INTEGER, N AS INTEGER) DECLARE FUNCTION Paiviksi% (pvm AS STRING) TYPE TKELLO paivat AS INTEGER '1.1.1980:sta kuluneet päivät minuutit AS STRING * 1 tunnit AS STRING * 1 sadasosat AS STRING * 1 sekunnit AS STRING * 1 END TYPE DIM kello AS TKELLO, vara AS TKELLO 'luetaan tämänhetkinen aika ja pistetään se talteen OPEN "CLOCK$" FOR BINARY AS #1 GET #1, , kello CLOSE #1 vara = kello GOSUB NaytaTiedot SLEEP 'muodostetaan päiväys 01.01.2000 12:34:56,00 kello.paivat = Paiviksi("01.01.2000") kello.tunnit = CHR$(12) kello.minuutit = CHR$(34) kello.sekunnit = CHR$(56) kello.sadasosat = CHR$(0) 'laitetaan uusi päiväys voimaan OPEN "CLOCK$" FOR BINARY AS #1 PUT #1, , kello CLOSE #1 GOSUB NaytaTiedot SLEEP 'palautetaan vanha päiväys ja luetaan se uudelleen OPEN "CLOCK$" FOR BINARY AS #1 PUT #1, , vara CLOSE #1 OPEN "CLOCK$" FOR BINARY AS #1 GET #1, , kello CLOSE #1 GOSUB NaytaTiedot END 'näyttää päivämäärän ja kellonajan kunnolla muotoiltuna NaytaTiedot: PRINT "Nyt on " + Paivaykseksi(kello.paivat) PRINT "Kello on " + MJ$(ASC(kello.tunnit), 1) + ":"; PRINT MJ$(ASC(kello.minuutit), 1) + ":"; PRINT MJ$(ASC(kello.sekunnit), 1) + ","; PRINT MJ$(ASC(kello.sadasosat), 1) RETURN 'palauttaa luvun merkkijonona, tarvittaessa etunollan kanssa FUNCTION MJ$ (L AS INTEGER, N AS INTEGER) IF N THEN MJ$ = RIGHT$("0" + LTRIM$(STR$(L)), 2) ELSE MJ$ = LTRIM$(STR$(L)) END IF END FUNCTION 'muuttaa päivien määrän päiväykseksi, esim. 8863 -> 07.04.2004 FUNCTION Paivaykseksi$ (paivat AS INTEGER) DIM v AS INTEGER, k AS INTEGER, p AS INTEGER v = 1980 k = 1 'lasketaan kokonaiset vuodet DO IF v MOD 4 = 0 THEN IF paivat < 366 THEN EXIT DO END IF paivat = paivat - 366 ELSE IF paivat < 365 THEN EXIT DO END IF paivat = paivat - 365 END IF v = v + 1 LOOP 'lasketaan kuukaudet DO SELECT CASE k CASE 4, 6, 9, 11 '30 päivää IF paivat < 31 THEN EXIT DO END IF paivat = paivat - 30 CASE 2 '28 tai 29 päivää IF v MOD 4 = 0 THEN IF paivat < 30 THEN EXIT DO END IF paivat = paivat - 29 ELSE IF paivat < 29 THEN EXIT DO END IF paivat = paivat - 28 END IF CASE ELSE '31 päivää IF paivat < 32 THEN EXIT DO END IF paivat = paivat - 31 END SELECT k = k + 1 LOOP 'päivät jää jäljelle p = paivat + 1 Paivaykseksi$ = MJ$(p, 1) + "." + MJ$(k, 1) + "." + MJ$(v, 0) END FUNCTION 'muuttaa päiväyksen päivien määräksi, esim. 07.04.2004 -> 8863 FUNCTION Paiviksi% (pvm AS STRING) DIM paivat AS INTEGER, i AS INTEGER DIM v AS INTEGER, k AS INTEGER, p AS INTEGER v = VAL(RIGHT$(pvm, 4)) k = VAL(MID$(pvm, 4, 2)) p = VAL(LEFT$(pvm, 2)) 'lasketaan vuosien tuottama päivien määrä FOR i = 1981 TO v IF i MOD 4 = 0 THEN 'karkausvuosi paivat = paivat + 366 ELSE 'tavallinen vuosi paivat = paivat + 365 END IF NEXT 'lasketaan kuukausien tuottama päivien määrä FOR i = 1 TO k - 1 SELECT CASE i CASE 4, 6, 9, 11 '30 päivää paivat = paivat + 30 CASE 2 '28 tai 29 päivää IF v MOD 4 = 0 THEN paivat = paivat + 29 ELSE paivat = paivat + 28 END IF CASE ELSE '31 päivää paivat = paivat + 31 END SELECT NEXT 'lisätään vielä jäljellejääneet päivät paivat = paivat + p '"stemmataan" päivien määrä IF v = 1980 OR v >= 2000 THEN paivat = paivat - 1 END IF Paiviksi% = paivat END FUNCTION
Aika hyvännäköistä koodia. Kai siitä joillekkin on hyötyä...
Huu! Onpas hyvä. Uudemmissa koneissa toi ei toimi siksi että se on taas "turvallisuusriskiaukko" ja "epävakaa" muka, mokoma protected mode!
apua. Peli haluaa tietää kellon ajan. Peli on virus. Poistetaan se. ~windowsin lähdekoodi