/* HUOM! T„ss„ tiedostossa olevien DEMO-teht„vien return-lauseet ovat vain h„m„yst„, jotta jokaista parametrina tuotua muuttujaa tulisi k„ytetty„ v„hint„„n 1. kerran (=> ei k„„nt„j„n valituksia). */ #include #include #include #include #include "pvm.h" typedef int KK_tyyppi[12]; /****************************************************************************/ /* Globaalit 'vakio'-tyyliset taulukot: */ char *VIIKON_PAIVAT[]={ "sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai" }; char *KUUKAUDET[]={ "", /* Tyhj„ jono paikkaan 0, jotta saadaan tammikuu 1:ksi */ "tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kes„kuu", "hein„kuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu" }; /* P„ivi„ kuukaudessa kun ei ole karkausvuosi : */ /* 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12 */ static KK_tyyppi PV_KK = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; /* Kuukauden 1. p„ivien j„rj. numerot (ei kv) */ static KK_tyyppi KK_1 = { 1, 32, 60, 91,121,152,182,213,244,274,305,335}; /****************************************************************************/ int /* 0 = ei karkausvuosi */ karkausvuosi( /* 1 = karkausvuosi */ int vuosi /* s Vuosi jota tutkitaan. */ ) /* ** Funktiolla palautetaan onko vuosi karkausvuosi vai ei. ** ** Algoritmi: 4:ll„ jaolliset on, paitsi t„ydet vuosisadat, kuitenkin ** 4:ll„ jaolliset vuosisadat on ** Esimerkki: 1991 -> 0, 1992 -> 1, 1900 -> 0, 2000 -> 1 ----------------------------------------------------------------------------*/ { /* DEMO karkausvuosi XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ return vuosi == 0; } /****************************************************************************/ void /* */ tayta_kk_1( /* */ int kk_1[] /* t Taul. johon tulee kk. 1. p„ivien j„rj.nro. */ ) /* ** Aliohjelmalla t„ytet„„n taulukko, josta selvi„„ kunkin kuukauden 1. p„iv„n ** j„rjestysnumero vuoden alusta laskien. T„ytt” ei kark.vuoden mukaan. ** ** Globaalit: PV_KK (g) - taulukko jossa on kuukausien pituudet ** Algoritmi: Ynn„t„„n kuukausien pituudet. ** Esimerkki: 1990 -> 1 32 60 91 ... ----------------------------------------------------------------------------*/ { kk_1[0] = 1; /* Tammikuu */ /* DEMO tayta_kk_1 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ } /****************************************************************************/ void /* */ tulosta_pvm( /* */ Pvm_tyyppi *pvm /* s Tulostettava p„iv„m„„r„ */ ) /* ** Aliohjelmalla tulostetaan p„iv„m„„r„ muodossa 5.11.1991 ** ** Tulostus: N„yt”lle ** Esimerkki: 5.11.1991 ----------------------------------------------------------------------------*/ { printf("%d.%d.%d",pvm->pv,pvm->kk,pvm->vv); } /****************************************************************************/ int /* */ selvita_1( /* = vuoden 1. p„iv„n nro su=0, ma=1,...la=6 */ int vuosi /* s Tutkittava vuosi. */ ) /* ** Funktiolla palautetaan vuoden 1. p„iv„n j„rjestysnumero ** ** Algoritmi: Tunnetaan 1.1.0001 = ma (Huom! Ei ole historiallisesti oikein!) ** Lasketaan vuosilukujen ero. ** Jokainen vuosi siirt„„ alkup„iv„„ yhdell„ eteenp„in, ** paitsi karkausvuodet. ----------------------------------------------------------------------------*/ { /* DEMO selvita_1 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ return vuosi; } /****************************************************************************/ int /* 0 = pvm OK */ tarkista_pvm( /* 1 = kk liian pieni */ /* 2 = kk liian suuri */ /* 3 = pv liian pieni */ /* 4 = pv liian suuri */ Pvm_tyyppi *pvm /* s Tutkittava p„iv„m„„r„ */ ) /* ** Funktiolla tutkitaan onko annettu p„iv„m„„r„ oikein. ** ** Globaalit: PV_KK (g taulukko) ** Algoritmi: Kuukausien pituudet katsotaan taulukosta PV_KK. ** Karkausvuoden helmikuussa pit„„ muistaa lis„t„ yksi. ----------------------------------------------------------------------------*/ { /* DEMO tarkista_pvm XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ return !pvm; } /****************************************************************************/ int /* */ paivan_numero( /* = p„iv„n numero vuoden alusta laskien. */ Pvm_tyyppi *pvm /* s Tutkittava p„iv„m„„r„ */ ) /* ** Funktiolla palautetaan p„iv„n numero kun 1.1 = 1 1.2 = 32 jne. ** ** Globaalit: KK_1 (g, taulukko) ** Algoritmi: Katsotaan kk:n 1. p„iv„n numero taulukosta ja ** karkausvuonna pit„„ maaliskuusta alkaen lis„t„ yksi. ----------------------------------------------------------------------------*/ { /* DEMO paivan_numero XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ return !pvm && !KK_1; } /****************************************************************************/ int /* */ muuta_viikoksi( /* = viikon numero */ Pvm_tyyppi *pvm /* s,t Tutkittava p„iv„m„„r„ */ ) /* ** Funktiolla muutetaan p„iv„m„„r„ viikonp„iv„ksi ja viikon numeroksi ** sek„ p„iv„n numeroksi. ** Virheellisest„ p„iv„m„„r„st„ palautetaan -1 ja pvm j„tet„„n ** koskemattomaksi. ** ** Kutsuu: tarkista_pvm ** paivan_numero ** selvita_1 ** Algoritmi: Viikon numero on 0, jos viikko alkaa pe, la tai su tammikuun ** alussa. Muuten viikon numero saadaan selville jakamalla ** p„iv„n juokseva j„rjestysnumero 7:ll„, kunhan muistetaan ** siirt„„ vuoden alkua sen mukaan, mill„ p„iv„ll„ vuosi alkaa. ** Jos vuosi alkaa p„iv„n numerosta ** ma, 1.1 on vkolla 1 ja ma 8.1 vkolla 2 7 -> 0+1 8 -> 1+1 ** ti, 1.1 1 ja ma 7.1 vkolla 2 6 -> 0+1 7 -> 1+1 ** ke, 1.1 1 ja ma 6.1 vkolla 2 5 -> 0+1 5 -> 1+1 ** to, 1.1 1 ja ma 5.1 vkolla 2 4 -> 0+1 4 -> 1+1 ** pe, 1.1 0 ja ma 4.1 vkolla 1 3 -> 0+0 3 -> 1+0 ** la, 1.1 0 ja ma 3.1 vkolla 1 2 -> 0+0 2 -> 1+0 ** su, 1.1 0 ja ma 2.1 vkolla 1 1 -> 0+0 1 -> 1+0 ----------------------------------------------------------------------------*/ { int pv_nro,vv_1; /* DEMO muuta_viikoksi XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ return pvm->vko && !&pv_nro && !&vv_1; } /****************************************************************************/ int /* */ muuta_pvmksi( /* = paivan numero vuoden alusta */ Pvm_tyyppi *pvm /* s,t Tutkittava p„iv„m„„r„ */ ) /* ** Funktiolla muutetaan p„iv„n„,viikkona ja vuotena annettu p„iv„ys muotoon ** pp kk vv ja pv_nro ** Virheellisest„ arvoista palautetaan -1 ja pvm j„tet„„n ** koskemattomaksi. ** ** Globaalit: PV_KK (g, taulukko) ** Kutsuu: tarkista_pvm ** paivan_numero ** selvita_1 ** Algoritmi: Viikon numero on 0, jos viikko alkaa pe, la tai su tammikuun ** alussa. ** Jos vuosi alkaa p„iv„n numerosta ** ma, 1.1 on vkolla 1 ja ma 8.1 vkolla 2 7 -> 0+1 8 -> 1+1 ** ti, 1.1 1 ja ma 7.1 vkolla 2 6 -> 0+1 7 -> 1+1 ** ke, 1.1 1 ja ma 6.1 vkolla 2 5 -> 0+1 5 -> 1+1 ** to, 1.1 1 ja ma 5.1 vkolla 2 4 -> 0+1 4 -> 1+1 ** pe, 1.1 0 ja ma 4.1 vkolla 1 3 -> 0+0 3 -> 1+0 ** la, 1.1 0 ja ma 3.1 vkolla 1 2 -> 0+0 2 -> 1+0 ** su, 1.1 0 ja ma 2.1 vkolla 1 1 -> 0+0 1 -> 1+0 ** Kun p„iv„n j„rj. numero on saatu selville, etsit„„n ** sit„ kuukautta, jossa ollaan. ----------------------------------------------------------------------------*/ { int pv_nro,vko,vv_1,paiva,kv,kk,pv,pv_kk; if ( (pvm->vko<0) || (pvm->vko>53) || (pvm->viikon_paiva<0) || (pvm->viikon_paiva>6) ) return -1; vv_1 = selvita_1(pvm->vv); if (vv_1==0) vv_1=7; /* Muutetaan su = 7 */ paiva = pvm->viikon_paiva; if (paiva==0) paiva=7; vko = pvm->vko - (1<=vv_1 && vv_1<=4); pv_nro = 7*vko - vv_1 + paiva + 1; if (pv_nro<0) return -1; kv = karkausvuosi(pvm->vv); if ( pv_nro-kv>366 ) return -1; for (pv=pv_nro,kk=0; kk<12; kk++) { pv_kk=PV_KK[kk]+(kv&&(kk==1)); if ( pv <= pv_kk ) break; pv -=pv_kk; } /* Tai: for (pv=pv_nro,kk=0; kk<12 && pv>(pv_kk=PV_KK[kk]+(kv&&kk==1)); kk++) pv -=pv_kk; */ pvm->pv = pv; pvm->kk = kk+1; pvm->pv_nro = pv_nro; return pv_nro; } /****************************************************************************/ void /* */ selvita_nyky_pvm( /* */ Pvm_tyyppi *nyky /* t T„m„n p„iv„n p„iv„m„„r„ */ ) /* ** Aliohjelmalla selvitet„„n t„m„n p„iv„n p„iv„m„„r„. ** ** Kutsuu: ** Tekij„: Vesa Lappalainen ** Pvm: 5.11.1991 ----------------------------------------------------------------------------*/ { time_t timer; struct tm *tblock; /* gets time of day */ timer = time(NULL); /* converts date/time to a structure */ tblock = localtime(&timer); nyky->pv = tblock->tm_mday; nyky->kk = tblock->tm_mon+1; nyky->vv = tblock->tm_year+1900; muuta_viikoksi(nyky); } /****************************************************************************/ int /* */ kysy_pvm( /* = moneenko kentt„„n vastattiin. */ Pvm_tyyppi *pvm, /* t kysytty p„iv„m„„r„ */ Pvm_tyyppi *oletus /* s oletusarvot, mik„li kentt„„ ei anneta */ ) /* ** Funktiolla kysyt„„n p„iv„m„„r„. Mik„li kaikkiin p„iv„m„„r„n kenttiin ei ** vastata, k„ytet„„n niihin oletusrvoja. Jos p„iv„m„„r„ on virheellinen, ** palautetaan -1. ** ** Sy”tt”: P„„tteelt„ ** Tulostus: N„ytt”lle ** Kutsuu: muuta_viikoksi ** Tulostus: N„ytt””n ** Esimerkki: oletus 5.11.1991, sy”tt” 12 -> 12.11.1991 ** 3.4 -> 3.4.1991 ** 2.3.1841 -> 2.3.1841 ----------------------------------------------------------------------------*/ { /* DEMO kysy_pvm XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ return !(pvm->pv=0 && oletus); } /****************************************************************************/ int /* 0 = sotun p„iv„m„„r„ oikein */ tarkista_sotu_pvm( /* 1 = sotun p„iv„m„„r„ v„„rin */ const char *sotu /* s Tutkittava sotu */ ) /* ** Funktiolla tarkistetaan onko annetussa sotussa p„iv„m„„r„ oikein. ** ----------------------------------------------------------------------------*/ { /* DEMO tarkista_sotu_pvm XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ return !sotu; }