Kirjautuminen

Haku

Tehtävät

Koodit: QB: CLOCK$:n käyttö

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

Kommentit

Heikki [08.04.2004 07:26:19]

#

Aika hyvännäköistä koodia. Kai siitä joillekkin on hyötyä...

sooda [08.04.2004 08:37:53]

#

Huu! Onpas hyvä. Uudemmissa koneissa toi ei toimi siksi että se on taas "turvallisuusriskiaukko" ja "epävakaa" muka, mokoma protected mode!

sammakkomies [05.12.2009 04:08:03]

#

apua. Peli haluaa tietää kellon ajan. Peli on virus. Poistetaan se. ~windowsin lähdekoodi

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta