24.11.2.24011910. Definirati i implementirati klasu “Datum” koja omogućava rad sa datumskim podacima. Klasa treba da sadrži sljedeće elemente:

  1. Privatne atribute koji čuvaju informaciju o danu, mjesecu i godini, pri čemu se informacija o mjesecu čuva kao cijeli broj u opsegu od 1 do 12;
  2. Konstruktor sa tri parametra koja postavlja atribute za dan, mjesec i godinu na osnovu informacija koje se prosljeđuju kroz parametre. U slučaju neispravnih informacija, konstruktor treba da baci izuzetak;
  3. Metode bez parametara koje služe za očitavanje informacija o danu, mjesecu i godini (kojima se ne može direktno pristupiti, s obzirom da predstavljaju privatne atribute);
  4. Metodu bez parametara koja vraća kao rezultat naziv dana u sedmici koji odgovara datumu (npr. ukoliko je u datumu zapamćen 24. 5. 2004. godine, metoda treba da vrati tekst “Ponedjeljak”, preciznije pokazivač na prvi znak teksta);
  5. Preklopljene operatore “++” i “––”, koji pomjeraju datum za jedan dan unaprijed odnosno unazad (potrebno je podržati i prefiksne i postfiksne verzije ovog operatora);
  6. Preklopljene operatore “+” i “–”, pri čemu je dozvoljeno je sabrati primjerak klase “Datum” sa pozitivnim cijelim brojem, odnosno oduzeti cijeli broj od primjerka klase “Datum”, gdje se kao rezultat dobija novi primjerak klase “Datum” u kojem je datum pomjeren unaprijed odnosno unazad za broj dana iskazan drugim parametrom (najjednostavnija, ali ujedno i dosta neefikasna ideja je primijeniti operator “++” odnosno “––“ u petlji neophodan broj puta).
  7. Preklopljeni operator “–” koji omogućava oduzimanje dva primjera klase “Datum”, pri čemu se kao rezultat dobija broj dana između dva datuma.
  8. Preklopljene relacione operatore “==”, “!=”,“<”,“>”,“<=” i “>=” koji daju rezultat poređenja dva datuma (u hronološkom poretku, tj. manji je onaj datum koji dolazi prije po kalendaru).
  9. Preklopljene operatore “+=” pri čemu “d += n” odnosno “d –= n” predstavlja prosto kraći zapis izraza “d = d + n” odnosno “d = d – n”.
  10. Preklopljeni operator “<<” za ispis datuma na ekran, pri čemu se prvo ispisuje redni broj dana, zatim tačka, zatim puno ime mjeseca (riječima) iza koje slijedi razmak, i konačno redni broj godine iza kojeg takođe slijedi tačka (Na primjer, ukoliko je u datumu zapamćen datum 3. 7. 2002. na ekranu treba da se ispiše "3. Juli 2002.").
  11. Preklopljeni operator “<<” za unos datuma sa tastature. Datum treba da se unosi u obliku dan/mjesec/godina, pri čemu su dan, mjesec i godina cijeli brojevi. U slučaju da unos nije ispravan (što uključuje i slučaj brojeva izvan dozvoljenog opsega), ulazni tok treba postaviti u neispravno stanje.
Sve metode implementirati izvan klase, osim trivijalnih metoda čija implementacija može stati u jedan red ekrana. Obavezno napisati i mali testni program u kojem će se testirati svi zahtijevani elementi ove klase.

Opis rješenja:

Listing programa:

#include <iostream>
#include <conio.h>
#include <cstring>
#include <cmath>

using namespace std;
class Datum{
int dan,mjesec,godina;
public:
Datum(int d,int m,int g);

int Ocitaj_d()const{return dan;}
int Ocitaj_m()const{return mjesec;}
int Ocitaj_g()const{return godina;}
char  *DUS(); 
friend Datum &operator++(Datum &d);
friend const Datum operator++(Datum &d,int);
friend Datum &operator--(Datum &d);
friend const Datum operator--(Datum &d,int);
friend  void operator+(Datum &d,int n){for(int i=0;i<n;i++)d++;}
friend  void operator-(Datum &d,int n){for(int i=0;i<n;i++)d--;}
friend int operator-(Datum &d1,Datum &d2);
friend bool operator==(Datum &d1,Datum &d2);
friend bool operator!=(Datum &d1,Datum &d2);
friend bool operator<(Datum &d1,Datum &d2);
friend bool operator>(Datum &d1,Datum &d2);
friend bool operator>=(Datum &d1,Datum &d2);
friend bool operator<=(Datum &d1,Datum &d2);
friend void operator+=(Datum &d,int n){d+n;}
friend void operator-=(Datum &d,int n){d-n;}
friend ostream &operator<<(ostream &cout,const Datum &d);
friend istream &operator>>(istream &cin, Datum &d);

void Ispis(){
    cout<<endl<<dan<<endl<<mjesec<<endl<<godina;
    }


};
Datum::Datum(int d=1,int m=1,int g=2005){
    int dani[12]={31,28,31,30,31,30,31,31,30,31,30,31};
    if(g%4==0&&g%100!=0||g%400==0)dani[1]++;
    if(g<1||m<1||d<1||m>12||d>dani[m-1])
        throw "neispravan datum!";
    dan=d;mjesec=m;godina=g;
}
char *Datum::DUS(){
char *sedmica[]={"Su","Ne","Po","Ut","Sr","Ce","Pe"};
int dani[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int D(0);
if(godina>2005){
    int G=godina,i(0);
    while(G>2005){
        if(G%4==0&&G%100!=0||G%400==0)i++;
        G--;
    }
    D=(godina-2005)*365+i;
}
else if(godina<2005){ 
    int G=godina,i(0);
    while(G<2005){ 
        G++;
       if(G%4==0&&G%100!=0||G%400==0)i++;
       }   

D=(2005-godina)*365+i;
}
if(godina>=2005){
    for(int i=0;i<mjesec-1;i++)
    D+=dani[i];
    D+=dan-1;
    }
else{
    if(godina%4==0&&godina%100!=0||godina%400==0)dani[1]++;
    for(int i=0;i<mjesec-1;i++)
    D+=dani[i];
    D+=dan-4;
}
    
    
return sedmica[abs(D%7)];
}
Datum &operator++(Datum &d){
int dani[12]={31,28,31,30,31,30,31,31,30,31,30,31};
if(d.dan==dani[d.mjesec-1]){
    if(d.mjesec==12){
       d.dan=1;d.mjesec=1;d.godina++;
    }
    
    else if(d.mjesec==2&&(d.godina%4==0&&d.godina%100!=0||d.godina%400==0))
    d.dan++;
    else{
    d.mjesec++;
    d.dan=1;
    }
}
else d.dan++;
return d;
}
const Datum operator++(Datum &d,int){
Datum D=d;
++d;
return D;
}
Datum &operator--(Datum &d){
int dani[12]={31,28,31,30,31,30,31,31,30,31,30,31};
if(d.godina%4==0&&d.godina%100!=0||d.godina%400==0)dani[1]++;
if(d.dan==1){
    if(d.mjesec==1){
        d.dan=dani[11];
        d.mjesec=12;
        d.godina--;
    }
    else {
        d.dan=dani[d.mjesec-2];
        d.mjesec--;
    }
}
else d.dan--;
return d;
}
const Datum operator--(Datum &d,int){
Datum D=d;
--d;
return D;
}
int operator-(Datum &d1,Datum &d2){
int dani[12]={31,28,31,30,31,30,31,31,30,31,30,31};
if(d1.godina%4==0&&d1.godina%100!=0||d1.godina%400==0)dani[1]++;
int br_dana(0);
if(d1.dan>=d2.dan){
    br_dana+=d1.dan-d2.dan;
    for(int i=d1.mjesec-1;i>d2.mjesec-1;i--)
        br_dana+=dani[i];
    }
else{
    for(int i=d1.mjesec-1;i>d2.mjesec;i--)
        br_dana+=dani[i];
        br_dana+=dani[d2.mjesec]-d2.dan+d1.dan-1;
    }
return br_dana;
}
bool operator==(Datum &d1,Datum &d2){
if(d1.dan==d2.dan&&d1.mjesec==d2.mjesec&&d1.godina==d2.godina)
    return true;
else return false;
}
bool operator!=(Datum &d1,Datum &d2){
if(d1.dan!=d2.dan||d1.mjesec!=d2.mjesec||d1.godina!=d2.godina)
    return true;
else return false;
}
bool operator<(Datum &d1,Datum &d2){
if(d1==d2)return false;
else if(d1.godina>d2.godina)return false;
else if(d1.godina<d2.godina)return true;
else if(d1.mjesec>d2.mjesec&&d1.godina==d2.godina)return false;
else if(d1.mjesec<d2.mjesec&&d1.godina==d2.godina)return true;
else if(d1.dan>d2.dan&&d1.mjesec==d2.mjesec&&d1.godina==d2.godina)return false;
else if(d1.dan<d2.dan&&d1.mjesec==d2.mjesec&&d1.godina==d2.godina)return true;
}
bool operator>(Datum &d1,Datum &d2){
if(d1==d2||d1<d2)return false;
else return true;
}
bool operator>=(Datum &d1,Datum &d2){
    if(d1>d2||d1==d2)return true;
    else return false;
} 
bool operator<=(Datum &d1,Datum &d2){
    if(d1<d2||d1==d2)return true;
    else return false;
} 
ostream &operator<<(ostream &cout,const Datum &d){
char *mj[]={"Jan","Feb","Mar","Apr","Maj","Jun","Jul","Avg","Sep","Okt","Nov","Dec"};   
return cout<<d.dan<<"."<<mj[d.mjesec-1]<<" "<<d.godina<<".";     
}       
istream &operator>>(istream &cin, Datum &d){
char znak,znak2;
int a,b,c;
cin>>ws;
cin>>a>>znak>>b>>znak2>>c;
try{
    Datum d(a,b,c);
    if(znak!='/'||znak2!='/'){
    cin.setstate(ios::failbit);throw "a";
    }  
}
catch(...){
throw;
}
return cin;
}
   
             
int main(){
try{
//Ovde treba testirati klasu...
}
catch(...){
cout<<"no datum!";
}
getch();
return 0;
}

Ispis na ekranu:

Riješeni zadaci 2    Index