Funktion gesucht die Datum in Tage umrechnet und Tage in Datum



  • Hallo zusammen ich suche Funktionen, die ein Datum (22.12.2013) in Tag umrechnet und eine Funktion die Tage in ein Datum umrechnet.

    Ich habe folgenden Algorithmus probiert, der allerdings nicht richtig zu funktionieren scheint:

    int Datum::fromDatetoNumbers(int tag, int monat, int jahr)
    {
    	monat= ((monat + 9) % 12);
    	jahr = (jahr - monat/10);
    	return (365*jahr + jahr/4 - jahr/100 + jahr/400 + (monat * 306 + 5)/10 + (tag -1));
    }
    
    void Datum::fromNumberstoDate(int tage) 
    {
    int y = (10000*tage + 14780)/3652425;
    int ddd = tage - (365*y + y/4 - y/100 + y/400);
    if (ddd < 0)
    {
    	y = y - 1;
    	ddd = tage - (365*y + y/4 - y/100 + y/400);
    }
    int mi = (100*ddd + 52)/3060;
    int mm = (mi + 2)%12 + 1;
    y = y + (mi + 2)/12;
    int dd = ddd - (mi*306 + 5)/10 + 1;
    cout << endl << endl << "Jahr: " << y << " Monat: " << mm << " Tag: " << dd;
    }
    

    Ich möchte halt zu einem Datum x-Tage hinzuaddieren und auch die Schaltjahre berücksichtigen.
    Erschien mir am einfachsten das Datum in Tage umzurechnen und dann die Addition zu vollführen um die Tage dann wieder zurück zu rechnen.


  • Mod

    Standardbibliothek? Boost?
    http://en.cppreference.com/w/cpp/chrono
    http://www.boost.org/doc/libs/1_54_0/doc/html/date_time.html

    Allgemein kann man bei der Handhabe von Datum und Zeit sehr viel falsch machen, das solltest du möglichst nicht selber programmieren. Ich würde sogar sagen, das ist der typische Fehler auf der Welt, weil jeder denkt, es wäre total einfach, was es aber nicht ist.



  • Das die Umrechnung nicht trivial ist, sehe ich an Hand der Algorithmen.

    Werde mir das mal anschauen und gucken ob ich das implementieren kann.


  • Mod

    Tyle schrieb:

    und gucken ob ich das implementieren kann.

    Wieso möchtest du nicht das fertige Rad benutzen?



  • Doch würde ich ja auch machen, weiss nur noch nicht wie ich die Bibliothek anspreche.

    Wurde hier auch schon mal gefragt:
    http://www.c-plusplus.net/forum/153859-full

    Leider ist der Link nicht mehr verfügbar.


  • Mod

    mktime kommt auch in meinen Links vor, wenn es nur um das benutzen geht.



  • Wo zu finden?


  • Mod

    Google? Oder die Suche auf den Referenzen? Du musst doch mittlerweile mal gelernt haben, wie man so etwas selber herausfindet. Oder wenn nicht, dann wird es höchste Zeit. Ist schließlich nicht weiter schwer, du brauchst bloß den Namen eintippen.



  • Ich dachte du meintest irgend eine Linkliste von dir die du hier im Forum erstellt hast.

    Klar kann ich die Infos auch per Google suchen... so schlimm stehts um mich noch net 😃



  • Ich möchte halt zu einem Datum x-Tage hinzuaddieren und auch die Schaltjahre berücksichtigen.

    Die Boost-Bibliotheken geben da eine einfache Möglichkeit:

    #include <iostream>
    
    #include <boost/date_time/gregorian/gregorian.hpp>
    
    int main()
    {
    	using namespace boost::gregorian;
    
        date d{2013, 07, 12};
    
        d = d + date_duration{100};
    
        std::cout << d << '\n';
    
        day_iterator iter{d};
    
        ++iter;
    
        std::cout << *iter;
    }
    

  • Mod

    Tyle schrieb:

    Ich dachte du meintest irgend eine Linkliste von dir die du hier im Forum erstellt hast.

    Die gibt's auch. Die ist auch nicht versteckt, sondern der alleroberste Thread:
    http://www.c-plusplus.net/forum/310212



  • Habe jetzt die Datumsprüfung so hinbekommen. Eigentlich gar net so schwer, wenn man mal kurz darüber nachdenkt:

    // Operator +=
    Datum& Datum::operator+=( int tage)
    {
    	tag_+= tage;
    	if(!isValid(tag_, monat_, jahr_))
    	{
    		while (!(isValid(tag_, monat_, jahr_)))
    		{
    			if (monat_ ==1 || monat_ == 3 || monat_ ==5 || monat_ == 7 || monat_ == 8 || monat_ == 10 || monat_ == 12) 
    				{
    					if (tag_ > 31) 
    					{
    						tag_ -= 31;
    				        monat_ ++;
    						if (monat_ > 12)
    						{
    							jahr_ ++;
    							monat_ -= 12;
    						}
    					}
    				}
    			else if (monat_ == 4 || monat_ == 6 || monat_ == 9 || monat_ ==11)
    			{
    				if (tag_ > 30) 
    				{
    					tag_ -= 30;
    				    monat_ ++;
    					if (monat_ > 12)
    					{
    						jahr_ ++;
    						monat_ -= 12;
    					}
    				}
    			}
    			else
    			{
    				if (schaltJahr(jahr_)) 
    				{
    				{
    					tag_ -= 29;
    				    monat_ ++;
    					if (monat_ > 12)
    					{
    						jahr_ ++;
    						monat_ -= 12;
    					}
    				}
    				}
    				else 
    				{
    					tag_ -= 28;
    				    monat_ ++;
    					if (monat_ > 12)
    					{
    						jahr_ ++;
    						monat_ -= 12;
    					}
    				}
    			}
    		}
    	}
    	return *this;
    }
    
    // Überprüft das Datum auf Gültigkeit, gibt true oder false zurück
    bool Datum::isValid(unsigned int tag_, unsigned int monat_, unsigned int jahr_)
    {
      if (! (1582<= jahr_ )  )//ab aktuelle jahresberechnung
         return false;
      if (! (1<= monat_ && monat_<=12) )// 12 monate checken
         return false;
      if (! (1<= tag_ && tag_<=31) ) // tage unter 31 liegen
         return false;
      if ( (tag_==31) && (monat_==2 || monat_==4 || monat_==6 || monat_==9 || monat_==11) ) // monate die keine 31 tage haben
         return false;
      if ( (tag_==30) && (monat_==2) ) // februar hat keine 31 tage
         return false;
      if ( (monat_==2) && (tag_==29) && (jahr_%4!=0) ) //februar auf schaltjahr prüfen - kein schaltjahr
         return false;
      if ( (monat_==2) && (tag_==29) && (jahr_%400==0) ) //februar auf schaltjahr prüfen - ist schaltjahr
         return true;
      if ( (monat_==2) && (tag_==29) && (jahr_%100==0) ) //februar auf schaltjahr prüfen - kein schaltjahr
         return false;
      if ( (monat_==2) && (tag_==29) && (jahr_%4==0)  ) //februar auf schlatjahr prüfen - ist schaltjahr
         return true;
    }
    
    // Auf Schaltjahr prüfen gibt true oder false zurück
    bool Datum::schaltJahr(int jahr) 
    {
    	if (jahr_%4!=0) //februar auf schaltjahr prüfen - kein schaltjahr
    		return false;
    	if (jahr_%400==0)//februar auf schaltjahr prüfen - ist schaltjahr
    		return true;
    	if (jahr_%100==0) //februar auf schaltjahr prüfen - kein schaltjahr
    		return false;
    	if (jahr_%4==0) //februar auf schlatjahr prüfen - ist schaltjahr
    		return true;
    }
    


  • Hallo zusammen ich habe nochmal eine Frage zum Programm:

    Und zwar habe ich ja zwei Klassen, Datum und Zeit. Nun soll Datum auch mit der Klasse Zeit operieren.

    Zu einem eine Frage zu der Warnung: "Nicht alle Steuerelementpfade geben einen Wert zurück."

    Eigentlich geben alle Abfragen ein true oder false zurück, muss ich da auch noch ein else zurückgeben oder warum kommt die Warnung?

    Was sagt die Warnung:

    main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: bool __thiscall Zeit::isValidTime(unsigned int,unsigned int)" (?isValidTime@Zeit@@QAE_NII@Z)" in Funktion ""public: __thiscall Zeit::Zeit(class Datum,unsigned int,unsigned int)" (??0Zeit@@QAE@VDatum@@II@Z)".

    aus? Das verstehe ich nicht so ganz. Ich vermute das er nicht richtig auf Datum zurückgreifen kann.

    Wäre super wenn mir jemand mal meine Fehler erklärt damit ich das verstehe.

    Dazu noch ein Punkt:
    Wenn ich die Klasse Zeit zu erst definiere bekomme ich auch einen Kompiler fehler:

    1>c:\users\outerheaven\documents\visual studio 2012\projects\aufgabe15-1\aufgabe15-1\main.cpp(31): error C2079: 'Zeit::datum' verwendet undefiniertes class 'Datum'
    1>c:\users\outerheaven\documents\visual studio 2012\projects\aufgabe15-1\aufgabe15-1\main.cpp(109): error C2440: 'Initialisierung': 'Datum' kann nicht in 'int' konvertiert werden

    Vor der Klassen definition von Zeit habe ich die Datums Klasse mit

    Datum datum;
    

    deklariert. S.u. einfach die Klassen Deklaration switchen, heißt zu erst Datum deklarieren, dann Datum definieren gefolgt von der Definition Zeit.

    Hier das Programm bisher:

    //#include "datum.hpp"
    //#include "zeit.hpp"
    //#include "termin.hpp"
    #include <iostream>
    #include <string>
    using namespace std;
    
    // Deklaration von Klasse Datum//
    class Datum {
    private:
    	//private Variablen Deklaration //
    	unsigned int tag_;
    	unsigned int monat_;
    	unsigned int jahr_;
    
    public:
    	// Methoden Deklaration //
    	void setTag(const int);
    	void setMonat(const int);
    	void setJahr(const int);
    	int getTag() const;
    	int getMonat() const;
        string getMonatString() const;
    	int getJahr() const;
    
    	// Konstruktor Deklaration //
    	// Überprüfungs Konstruktor
    	Datum(unsigned int, unsigned int, unsigned int);
    	// Standard Konstruktor
    	Datum();
    	// Destruktor Deklaration
    	~Datum();
    	// Überladungs Deklarationen //
    	// Operator <<
    	friend ostream& operator<<(ostream &, const Datum &);
        //Operator >>
        friend istream& operator>>(istream &, const Datum &);
    	// Operator =
        Datum &operator=(const Datum &rh);
    	// Operator ==
        bool operator==(const Datum &r);
    	// Operator +=
        Datum &operator+=( int tage);
    
    	// Methoden(Funktionen) Deklaration
    	bool isValid(unsigned int, unsigned int, unsigned int);
    	bool schaltJahr(int);
    
    };
    
    class Zeit {
    private:
    	//Variablen Deklaration//
    	unsigned int stunden_;
    	unsigned int minuten_;
    
    public:
    	void setStunden(const int);
    	void setMinuten(const int);
    	int getMinuten() const;
    	int getStunden() const;
    	//Konstruktor Deklaration//
    	Zeit();
    	Zeit(Datum, unsigned int, unsigned int);
    	Datum datum;
    
    	//Funktionen Deklaration//
    	bool isValidTime(unsigned int, unsigned int);
    	void makeValidTime();
    
    	// Überladungs Deklarationen //
    	// Operator <<
    	friend ostream &operator<<(ostream &, const Zeit &);
    	// Operator +=
        Zeit &operator+=( int minuten);
    
    };
    
    // Set-Methoden Definitionen //
    void Zeit::setStunden(const int x) {stunden_=x; return;}
    void Zeit::setMinuten(const int y) {minuten_=y; return;}
    
    // Get-Methoden Definitionen //
    // Minuten
    int Zeit::getMinuten() const 
    {
    	return minuten_;
    }
    
    // Stunden
    int Zeit::getStunden() const 
    {
    	return stunden_;
    }
    
    // Konstruktor Definitionen //
    // Konstruktor mit Prüfung --> Definition
    Zeit::Zeit(Datum d1, unsigned int m, unsigned int s) :  datum(d1), minuten_(m), stunden_(s)
    {
        std::cout << "Konstruktor mit Ueberpruefung" << endl;
    	{
        if (!isValidTime(minuten_, stunden_))
        {
    	  std::cout << "Zeit ist ungueltig!" << endl;
    	  minuten_ = 00;
    	  stunden_ = 00;
        }
      }
    }
    
    // Konstruktor ohne Überprüfung
    // Standardkonstruktor
    Zeit::Zeit() : minuten_(00), stunden_(00)
    {
    	std::cout << "Konstruktor ohne Ueberpruefung" << endl;
    	return;
    }
    
    // Operator +=
    Zeit& Zeit::operator+=( int minuten)
    {
    	minuten_+= minuten;
    
    	if(!isValidTime(minuten_, stunden_)) makeValidTime(); //makeValidTime wird noch geändert wie im Datum
    
    	return *this;
    }
    
     // Operator <<
    ostream& operator<<(ostream &os, const Zeit &z)
    {
    os << z.getMinuten() << ":" <<z.getStunden();
    return os;
    }
    
    //Funktionen Definition//
    bool isValidTime(unsigned int minuten_, unsigned int stunden_) 
    {
    	if (minuten_ >= 0 && minuten_ <=59)
    	{
    		if (stunden_ >= 0 && stunden_ <= 23)
    		{
    			return true;
    		}
    	}
    	else return false;
    }
    void makeValidTime() {}// Wird später nicht mehr gebraucht
    //------------------------------------------------------------------------------
    
    // Set-Methoden Definitionen //
    void Datum::setTag(const int t) {tag_=t; return;}
    void Datum::setMonat(const int m) {monat_=m; return;}
    void Datum::setJahr(const int j) {jahr_=j; return;}
    
    // Get-Methoden Definitionen //
    // Tag
    int Datum::getTag() const 
    {
    	return tag_;
    }
    // Monat
    int Datum::getMonat() const 
    {
    	return monat_;
    }
    // Jahr
    int Datum::getJahr() const {
    	return jahr_;
    }
    
    //Zahlen in Monatsdaten konvertieren für Ausgabe
    string Datum::getMonatString() const
    {
        switch (monat_)
        {
            case 1:
                return "Januar";
            case 2:
                return "Februar";
            case 3:
                return "Maerz";
            case 4:
                return "April";
            case 5:
                return "Mai";
            case 6:
                return "Juni";
            case 7:
                return "Juli";
            case 8:
                return "August";
            case 9:
                return "September";
            case 10:
                return "Oktober";
            case 11:
                return "November";
            case 12:
                return "Dezember";
            default:
                return "Undefined";
        }
    }
    
    // Konstruktor Definitionen //
    // Konstruktor mit Prüfung --> Definition
    Datum::Datum(unsigned int t, unsigned int m, unsigned int j) : tag_(t), monat_(m), jahr_(j)
    {
        cout << "Konstruktor mit Ueberpruefung" << endl;
    	{
        if (!isValid(t,m,j))
        {
    	  cout << "Datum ist ungueltig!" << endl;
    	  tag_ = 1;
    	  monat_ = 1;
    	  jahr_ = 1900;
        }
      }
    }
    
    //Konstruktor ohne Überprüfung
    Datum::Datum() : tag_(1), monat_(1), jahr_(1900)
    {
    	cout << "Konstruktor ohne Ueberpruefung" << endl;
    	return;
    }
    
    // Destruktor //
    Datum::~Datum() {} 
    
    // Überladungs Definitionen
    // Erklärung für Überladungen
    //Rückgabetyp Funktionsname (Parameter)
    //{
    //    Anweisungen
    //}
    
    // Operator >>
    istream &operator>>(istream& is, Datum& z)
    {
        unsigned int t, m, j;
    //    scanf("%2d %2d %4d", &t, &m, &j);
        scanf("%i %i %i", &t, &m, &j);
    
    //    cout << t << "." << m << "." << j << endl; 
        z.setTag(t);
        z.setMonat(m);
        z.setJahr(j);
        return is;
    }
    
    // Operator <<
    ostream& operator<<(ostream& os, const Datum& z)
    {
    os << z.getTag() << "." <<z.getMonatString() << " "<<z.getJahr();
    return os;
    }
    
    // Operator =
    Datum& Datum::operator=(const Datum& rh)
    {
        this->tag_ = rh.tag_;
        this->monat_ = rh.monat_;
        this->jahr_ = rh.jahr_;
    
        return *this;
    }
    
    // Operator ==
    //bool operator==(const Datum &l, const Datum &r)
    //{
    //	return l.getJahr() == r.getJahr() && l.getMonat() == r.getMonat() && l.getTag() == r.getTag();
    //}
    bool Datum::operator==(const Datum &r)
    {
    	return this->getMonat() == r.getMonat() && this->getTag() == r.getTag();
    	//this->getJahr() == r.getJahr() &&  //Vergleiche auch Jahreszahlen
    }
    
    // Operator +=
    Datum& Datum::operator+=( int tage)
    {
    	tag_+= tage;
    	if(!isValid(tag_, monat_, jahr_))
    	{
    		while (!(isValid(tag_, monat_, jahr_)))
    		{
    			if (monat_ ==1 || monat_ == 3 || monat_ ==5 || monat_ == 7 || monat_ == 8 || monat_ == 10 || monat_ == 12) 
    				{
    					if (tag_ > 31) 
    					{
    						tag_ -= 31;
    				        monat_ ++;
    						if (monat_ > 12)
    						{
    							jahr_ ++;
    							monat_ -= 12;
    						}
    					}
    				}
    			else if (monat_ == 4 || monat_ == 6 || monat_ == 9 || monat_ ==11)
    			{
    				if (tag_ > 30) 
    				{
    					tag_ -= 30;
    				    monat_ ++;
    					if (monat_ > 12)
    					{
    						jahr_ ++;
    						monat_ -= 12;
    					}
    				}
    			}
    			else
    			{
    				if (schaltJahr(jahr_)) 
    				{
    				{
    					tag_ -= 29;
    				    monat_ ++;
    					if (monat_ > 12)
    					{
    						jahr_ ++;
    						monat_ -= 12;
    					}
    				}
    				}
    				else 
    				{
    					tag_ -= 28;
    				    monat_ ++;
    					if (monat_ > 12)
    					{
    						jahr_ ++;
    						monat_ -= 12;
    					}
    				}
    			}
    		}
    	}
    	return *this;
    }
    
    // Überprüft das Datum auf Gültigkeit, gibt true oder false zurück
    bool Datum::isValid(unsigned int tag_, unsigned int monat_, unsigned int jahr_)
    {
      if (! (1582<= jahr_ )  )//ab aktuelle jahresberechnung
         return false;
      if (! (1<= monat_ && monat_<=12) )// 12 monate checken
         return false;
      if (! (1<= tag_ && tag_<=31) ) // tage unter 31 liegen
         return false;
      if ( (tag_==31) && (monat_==2 || monat_==4 || monat_==6 || monat_==9 || monat_==11) ) // monate die keine 31 tage haben
         return false;
      if ( (tag_==30) && (monat_==2) ) // februar hat keine 31 tage
         return false;
      if ( (monat_==2) && (tag_==29) && (jahr_%4!=0) ) //februar auf schaltjahr prüfen - kein schaltjahr
         return false;
      if ( (monat_==2) && (tag_==29) && (jahr_%400==0) ) //februar auf schaltjahr prüfen - ist schaltjahr
         return true;
      if ( (monat_==2) && (tag_==29) && (jahr_%100==0) ) //februar auf schaltjahr prüfen - kein schaltjahr
         return false;
      if ( (monat_==2) && (tag_==29) && (jahr_%4==0)  ) //februar auf schlatjahr prüfen - ist schaltjahr
         return true;
    }
    
    // Auf Schaltjahr prüfen gibt true oder false zurück
    bool Datum::schaltJahr(int jahr) 
    {
    	if (jahr_%4!=0) //februar auf schaltjahr prüfen - kein schaltjahr
    		return false;
    	if (jahr_%400==0)//februar auf schaltjahr prüfen - ist schaltjahr
    		return true;
    	if (jahr_%100==0) //februar auf schaltjahr prüfen - kein schaltjahr
    		return false;
    	if (jahr_%4==0) //februar auf schlatjahr prüfen - ist schaltjahr
    		return true;
    }
    
    //----------------------------------------------------------------------------------------------
    int main() {
      Datum d1;
      Datum d2(10,12,2012);
    
      cout << "Datum d1: " << d1 << endl;
      cout << "Datum d2: " << d2 << endl << endl;
    
      cout << "Versuche d3 mit Datum 29.02.2007 anzulegen" << endl;
      Datum d3(29,2,2007);
      cout << "Datum d3: " << d3 << endl << endl;
    
      cout << "Vergleiche d1 mit d2 und d3: " << endl;
      cout << "d1==d2: " << (d1==d2) << endl;
      cout << "d1==d3: " << (d1==d3) << endl << endl;
    
      cout << "Setze d1 auf Wert von d2" << endl;
      d1 = d2;
      cout << "Datum d1: " << d1 << endl << endl;
    
      cout << "Addiere 100 Tage zu d1" << endl;
      d1 += 100;
      cout << "Datum d1: " << d1 << endl;
      cout << "Addiere 60 Tage zu d2" << endl;
      d2 += 60;
      cout << "Datum d2: " << d2 << endl << endl;
    
      cout << "Datum im Format \"tt mm jjjj\" eingeben: "; cout.flush();
      cin >> d1;
      cout << "Speichere eingegebenes Datum in d1" << endl;
      cout << "Datum d1: " << d1 << endl << endl;  
    
      Zeit z1(d1,22,30);
      cout << "Zeitpunkt z1: " << z1 << endl;
      cout << "Versuche Zeit z2 mit d1 und Zeit 25:10 Uhr anzulegen: " << endl;
      Zeit z2(d1,25,10);
      z1 += 100;
    // Identisch zu: z1.operator+=(100);
      cout << "Addiere 100 Minuten zu z1: " << z1 << endl << endl;
    
      Zeit z3(d2,22,30);
      cout << "Zeitpunkt z3: " << z3 << endl;
      z3 += 2000;
      cout << "Addiere 2000 Minuten zu Zeitpunkt z3: " << z3 << endl << endl;
    //
    //  Termin t1(Zeit(Datum(7,2,2013),10,0),"OOP Klausur",90);
    //  cout << "Erstelle Termin mit 90 Minuten Dauer: " << endl << t1 << endl;
    
      system("pause");
      return 0;
    }
    

  • Mod

    Tyle schrieb:

    Zu einem eine Frage zu der Warnung: "Nicht alle Steuerelementpfade geben einen Wert zurück."

    Das heißt, dass es mögliche Programmablaufpfade gibt, in denen es vorkommen könnte, dass die Datusprüfngsfunktion ohne return endet. Was undefiniertes Verhalten wäre. Der Compiler hat auch vollkommen Recht, denn was passiert den Beispielsweise, wenn ein ganz normales, gültiges Datum eingegeben wurde?

    muss ich da auch noch ein else zurückgeben [...]?

    Wäre eine der Möglichkeiten. Auf jeden Fall aber nochmal grünlich nachdenken, ob du überhaupt alle Fälle abdeckst. Was passiert mit dem 1.1.1999?

    Was sagt die Warnung:

    main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: bool __thiscall Zeit::isValidTime(unsigned int,unsigned int)" (?isValidTime@Zeit@@QAE_NII@Z)" in Funktion ""public: __thiscall Zeit::Zeit(class Datum,unsigned int,unsigned int)" (??0Zeit@@QAE@VDatum@@II@Z)".

    aus? Das verstehe ich nicht so ganz. Ich vermute das er nicht richtig auf Datum zurückgreifen kann.

    Das ist keine Warnung, sondern ein Linkerfehler. Du hast irgendwo deklariert, dass du eine Funktion bool Zeit::isValidTime(unsigned int,unsigned int) hast, aber diese nirgends definiert hast. Kann ich nachvollziehen, denn ich sehe sie ebenfalls nirgendwo. Ich sehe jedoch eine Funktion bool isValidTime(unsigned int, unsigned int) . Verdächtig.

    Dazu noch ein Punkt:
    Wenn ich die Klasse Zeit zu erst definiere bekomme ich auch einen Kompiler fehler:

    1>c:\users\outerheaven\documents\visual studio 2012\projects\aufgabe15-1\aufgabe15-1\main.cpp(31): error C2079: 'Zeit::datum' verwendet undefiniertes class 'Datum'
    1>c:\users\outerheaven\documents\visual studio 2012\projects\aufgabe15-1\aufgabe15-1\main.cpp(109): error C2440: 'Initialisierung': 'Datum' kann nicht in 'int' konvertiert werden

    Vor der Klassen definition von Zeit habe ich die Datums Klasse mit

    Datum datum;
    

    deklariert. S.u. einfach die Klassen Deklaration switchen, heißt zu erst Datum deklarieren, dann Datum definieren gefolgt von der Definition Zeit.

    Eine Forward-Deklaration reicht aus, um damit Pointer und Referenzen auf eine Klasse zu deklarieren und definieren und um diese Klasse als Parameter oder Rückgabewert in einer Funktionsdeklaration zu benutzen. Deine Zeitklassendefinition enthält ein Datumsmember. Daher muss genau bekannt sein, was ein Datum überhaupt ist.



  • Das ist keine Warnung, sondern ein Linkerfehler. Du hast irgendwo deklariert, dass du eine Funktion bool Zeit::isValidTime(unsigned int,unsigned int) hast, aber diese nirgends definiert hast. Kann ich nachvollziehen, denn ich sehe sie ebenfalls nirgendwo. Ich sehe jedoch eine Funktion bool isValidTime(unsigned int, unsigned int). Verdächtig.

    Ahhh OK, d.h. ich habe dort den Scope Operator vergessen, da ja die Funktion ein Member von Zeit ist. Ohne den Scope Operator kann der Kompiler nicht wissen das die Funktion ein Member ist und sucht nach einer normalen Funktion, die ja nicht vorhanden ist. Richtig?

    Das mit der Warning lässt sich mit einem else beheben. Dann würde der Fall 1.1.1999 auch zurückgeben, dass es sich um ein gültiges Datum handelt, was es ja auch ist.


  • Mod

    Tyle schrieb:

    Ahhh OK, d.h. ich habe dort den Scope Operator vergessen, da ja die Funktion ein Member von Zeit ist. Ohne den Scope Operator kann der Kompiler nicht wissen das die Funktion ein Member ist und sucht nach einer normalen Funktion, die ja nicht vorhanden ist. Richtig?

    Falsch. Member oder frei Funktion ist erst einmal egal, das ist so, als ob das zwei Funktionen mit unterschiedlichem Namen wären. Zur Erklärung nehmen wir einfach mal an, die Namen wären tatsächlich verschieden, "Foo" und "Bar". Dann hast du gemacht:

    bool Foo(unsigned, unsigned);  // Deklaration der Funktion Foo. Es ist dem 
    // Compiler nun bekannt, dass es diese Funktion irgendwo gibt.
    
    // Definition der Funktion Bar:
    bool Bar(unsigned, unsigned)
    {
      // Quellcode
    }
    // Es ist dem Compiler nun bekannt, dass es diese Funktion gibt und es wurde 
    // Maschinencode erzeugt für diese Funktion.
    
    int main()
    {
      Foo(1,2);   // Aufruf der Funktion Foo. Der Compiler weiß, dass diese
     // Funktion existiert (siehe oben) und kann die Parameter überprüfen (passt!).
     // Es wird Maschinencode zum Aufruf dieser Funktion erzeugt.
    }
    

    Nachdem der Compiler diesen Maschinencode erzeugt hat, kommt der Linker dran (im Folgenden vereinfachte Darstellung, was Linken ist). Der sucht nach Funktionsaufrufen und dem dazu passenden Maschinencode der Funktionen und setzt alle Adressen richtig (der Compiler wusste zwar, welche Funktionen es gibt, aber er weiß nicht unbedingt, wo genau im Programm der Maschinencode der Funktionen stehen wird, da zu der zeit noch nicht klar ist, wie das Programm am Ende überhaupt aufgebaut ist). Nun findet er den Aufruf der Funktion, aber nirgendwo gibt es Maschinencode für diese Funktion. -> Fehler.

    Das mit der Warning lässt sich mit einem else beheben. Dann würde der Fall 1.1.1999 auch zurückgeben, dass es sich um ein gültiges Datum handelt, was es ja auch ist.

    Kommt drauf an, wo genau du das else gesetzt hast. Deine Funktion ist etwas wild. Blickst du selber noch durch?



  • Ok das mit dem Linker erscheint mir plausiebel.

    Kommt drauf an, wo genau du das else gesetzt hast. Deine Funktion ist etwas wild. Blickst du selber noch durch?

    Ja, ich blick noch durch. Hätte man sicherlich auch noch kürzer machen können, ich habe aber einfach nur simpel die Fälle abgearbeitet.

    // Überprüft das Datum auf Gültigkeit, gibt true oder false zurück
    bool Datum::isValid(unsigned int tag_, unsigned int monat_, unsigned int jahr_)
    {
      if (! (1582<= jahr_ )  )//ab aktuelle jahresberechnung
         return false;
      if (! (1<= monat_ && monat_<=12) )// 12 monate checken
         return false;
      if (! (1<= tag_ && tag_<=31) ) // tage unter 31 liegen
         return false;
      if ( (tag_==31) && (monat_==2 || monat_==4 || monat_==6 || monat_==9 || monat_==11) ) // monate die keine 31 tage haben
         return false;
      if ( (tag_==30) && (monat_==2) ) // februar hat keine 31 tage
         return false;
      if ( (monat_==2) && (tag_==29) && (jahr_%4!=0) ) //februar auf schaltjahr prüfen - kein schaltjahr
         return false;
      if ( (monat_==2) && (tag_==29) && (jahr_%400==0) ) //februar auf schaltjahr prüfen - ist schaltjahr
         return true;
      if ( (monat_==2) && (tag_==29) && (jahr_%100==0) ) //februar auf schaltjahr prüfen - kein schaltjahr
         return false;
      if ( (monat_==2) && (tag_==29) && (jahr_%4==0)  ) //februar auf schlatjahr prüfen - ist schaltjahr
         return true;
      else return true;
    }
    

    Am Ende hat er alle Fälle durch, wenn jetzt kein Fall zutrift, dann ist das Datum ein valides Datum.

    Bei meinem Programm ist mir aber noch etwas aufgefallen, dass wenn ich für Zeit den += Operator überlade, die Minuten mit den Stunden vertauscht werden.

    Habe den Konstruktor entsprechend angepasst und auch die Überladung vom << Operator. Wird jetzt in der Richtigen Reihenfolge ausgegeben.


  • Mod

    Genau das hatte ich befürchtet, du blickst selber nicht mehr durch:

    if ( (monat_==2) && (tag_==29) && (jahr_%4==0)  ) //februar auf schlatjahr prüfen - ist schaltjahr
         return true;
      else return true;
    

    Aha. Im Fall 1 ist das Datum gültig, andernfalls auch. Immer noch sicher?



  • Genau das hatte ich befürchtet, du blickst selber nicht mehr durch:
    C++:
    if ( (monat_==2) && (tag_==29) && (jahr_%4==0) ) //februar auf schlatjahr prüfen - ist schaltjahr
    return true;
    else return true;
    Aha. Im Fall 1 ist das Datum gültig, andernfalls auch. Immer noch sicher?

    Der Else-Fall tritt nur ein wenn es ein gültiges Datum ist. Das ist schon richtig so...


  • Mod

    Wenn du meinst, dass ich mit dem Zaunpfahl nur zum Spaß gewunken habe, darfst du das auch gerne so lassen. Sag hinterher nicht, dass du nicht gewarnt wurdest.


Log in to reply