Enrere Mòdul 7
Fonaments de programació. Llenguatge C/C++---
Pràctica    Resum teòric Exercicis
Pràctica d'ampliació

 
Obtenció del dia i la hora del Sistema Operatiu

En aquesta pràctica aprendrem a manipular estructures, enumerats, i algunes funcions per obtenir i manipular temps.

 

Desenvolupament de la pràctica

Aquesta pràctica consta de dos programes, i per tant, dos projectes: m7p031 i m7p032. Cada projecte contindrà un fitxer de codi font C/C++ anomenats: m7p031.cpp i m7p032.cpp.

El primer dels programes té el següent codi:

//m7p031.cpp: Obtenció del dia i la hora del Sistema Operatiu

#include <stdio.h>
#include <time.h>

enum emes{gener,febrer,marc,abril,
          maig,juny,juliol,agost,setembre,
          octubre,novembre,desembre

};

struct instant{
           int any;
           enum emes mes;
           int dia;
           int hora;
           int minut;
           int segon;
};
int dies_mes[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int dies_any[4]={366,365,365,365};
char *nom_mes[12]={"gener", "febrer","març","abril","maig",
"juny","juliol","agost","setembre","octubre",
"novembre","desembre"};


void main(){
    int t;
    instant ara={1970,gener,1,0,0,0};
    t=time(NULL);

    while (t-dies_any[ara.any%4]*24*3600>0){
           t=t-dies_any[ara.any%4]*24*3600;
           ara.any++;
    }

    while (t-24*3600*dies_mes[ara.mes]>0){
           t=t-24*3600*dies_mes[ara.mes];

                     if(!(ara.any%4)&&ara.mes==febrer)t=t-24*3600;
           ara.mes=emes(ara.mes+1);
    }


    while (t-24*3600>0){
           ara.dia++;
           t=t-24*3600;
    }

    while (t-3600>0){
          ara.hora++;
          t=t-3600;
    }

    ara.hora=ara.hora+2; /* (Franja horària Espanya=GMT+1)
                         en estiu és GMT+2*/

    while(t-60>0){
          ara.minut++;
          t=t-60;
    }

    ara.segon=t;



    printf("any:%d, mes:%s, dia:%d, hora:%d, minut:%d, segon:%d\n",ara.any, nom_mes[ara.mes], ara.dia, ara.hora, ara.minut, ara.segon);
}




Explicació del programa

Una de les funcions importants de la llibreria estàndard de C/C++ és la funció time(). Aquesta funció, el protocol de la qual es troba en time.h, torna el nombre de segons que han transcorregut des de les 00 hores de l'1 de gener de 1970. Aquesta informació es pot obtenir amb aquesta funció de dues formes:

  • directament amb el valor de retorn de la funció.
  • passant a aquesta funció un punter a long int. Aquesta funció col·loca a l'adreça apuntada per aquest punter el nombre de segons abans esmentat.

En el programa m7p031.cpp es fa servir la primera de les formes, en aquest cas, es passa com argument un punter NULL.

 
    int t;
    ...
    t=time(NULL);

A partir de la informació obtinguda de la funció time(), el programa obtindrà l'any, el mes, el dia, l'hora, el minut i el segon. Per això s'ha definit una estructura anomenada instant. Aquesta estructura consta de sis camps anomenats: any, mes, dia, hora, minut, segon. Tots són enters menys el camp mes, que s'ha definit de tipus enum emes. Aquest últim tipus és un tipus enumerat definit abans. Una variable de tipus emes (o enum emes) només pot prendre un valor dels 12 possibles (gener, febrer,...). 

Ja dins de la funció main() es declara una variable d'estructura anomenada ara. Aquesta variable ara té l'estructura instant. No s'ha de confondre estructura amb variable estructura, encara que a vegades es fa servir la primera paraula per referir-se a la segona expressió.

En la declaració d'aquesta variable ara es fa la inicialització:

 
instant ara={1970,gener,1,0,0,0};

La inicialització es fa de la mateixa forma que amb els vectors, és a dir, posant a continuació del nom de la variable la llista dels valors separats entre comes i tots ells tancats entre claus.

En ANSI C, aquesta declaració hauria d'haver començat per la paraula struct. En C++, no és necessari posar aquesta paraula en les declaracions de variables d'estructura (encara que no és incorrecte posar-la).

Els valors inicials de la variable ara corresponen a les 00 hores, 00 minuts i 00 segons del dia 1 de gener de 1970.

Els diferents camps d'aquesta variable estructura es referencien amb l'operador punt (.), per exemple, ara.any, ara.mes,...

Amb el valor de t, trobarem l'any. Això es fa restant a t els segons que tenen respectivament els anys, 1970, 1971, ... i sumant al camp any de la variable ara, 1 per cada any sencer que restem. Això es fa amb aquestes línies:

 
 int dies_any[4]={366,365,365,365};
 ..............
 while (t-dies_any[ara.any%4]*24*3600>0){
         t=t-dies_any[ara.any%4]*24*3600;
           ara.any++;
    }

La condició de la sentència while: t-dies_any[ara.any%4]*24*3600>0 comprova que en la variable t hi ha suficients segons per treure-li un any, si l'any és de traspàs, ara.any%4 és igual a 0 i dies_any[ara.any%4]=366, per tant, traiem 366*24*3600 segons que té un any de traspàs. Si l'any no és de traspàs, ara.any%4 serà igual a 1, 2 o 3 i, en aquest cas, dies_any[ara.any%4]=365, per tant, traiem 365*24*3600 segons. Aquest bucle es repeteix fins que el nombre de segons no arribi a un any.

El següent bucle calcula el mes de la mateixa forma. Treu els dies corresponents a cada mes fins que el nombre de segons no arribi a un mes, i així successivament. En el cas dels mesos, si estem en un any de traspàs i en el mes de febrer, es treu un dia més.

Respecte al càlcul de l'hora fa falta un comentari: l'hora tornada per la funció time() és l'hora GMT (Greenwich mean time). En Espanya s'ha de sumar 1 o 2 hores segons sigui hivern o estiu respectivament.

La impressió del resultat es fa amb la funció printf(). És important notar que les variables d'enumeració com ara.mes són considerades variables enteres. Per defecte, si no s'indica el contrari, el primer valor (gener) correspon a 0, el segon valor (febrer) a 1, i així respectivament.

És evident que per trobar el dia i l'hora del Sistema Operatiu no és necessari tot el programa anterior. Aquesta només pretén ser una pràctica d'estructures i variables d'enumeració. 

Per completar aquesta pràctica veurem algunes de les moltes funcions de manipulació de temps que incorpora la biblioteca estàndard de C/C++. En el següent programa veurem les funcions _strtime() i _strdate(). Ambdues funcions (que no corresponen a l'estàndard ANSI C) permeten extraure en forma de cadena de caràcters l'hora i la data. Per tal de fer servir aquestes dues funcions també es necessita l'arxiu de capçalera time.h

 

 
//m7p032.cpp: Obtenció del dia i la hora del Sistema Operatiu

#include <stdio.h>
#include <time.h>

void main(){
    char cad[9];
    _strtime( cad );
    printf( "Hora del Sistema Operatiu:\t%s\n", cad );     

    _strdate( cad );
    printf( "Data del Sistema Operatiu:\t%s\n", cad );
}


Tant la funció _strtime com la funció _strdate admeten com argument un punter char*. Les dues funcions emmagatzemen en aquesta variable de cadena  (concretament en 8 caràcters) l'hora o el dia.