Tag Monat Jahr korrekt berrechnen!

Marc T.

Bekanntes Mitglied
Halli Hallo,

ich hab hier mal was programmiert (ich weiß das gibt es fertig, war nur zum Spaß 😉),
und jetzt ist iwo nen klitze-kleiner Fehler drin aber er will von mir derzeit nicht
gefunden werden.... ist bestimmt iwas ganz leichtes offensichtliches aber ich steh seid
ein paar Stunden auf dem Schlauch 😉

Ich habe hier erst einmal so meine Millisekunden, Sekunden, Minuten, Stunden und Tage
berrechnet:

Java:
time = System.currentTimeMillis();
long temp = time;
		
this.setMilliSecond((int)(temp % 1000));
temp /= 1000;
this.setSecond((int)(temp % 60));
temp /= 60;
this.setMinute((int)(temp % 60));
temp /= 60;
this.setHour((int)(temp % 24));
temp /= 24;
		
setYearMonthDay((int)temp);

Und dann wollte ich mit setYearMonthDay((int)temp); meine
restlichen Daten ermitteln (tage, monate, jahre)

Die setYearMonthDay Methode sieht wie folgt aus:

Java:
private void setYearMonthDay(int days) {
	int tempYear = 1970;
	int tempMonth = JANUARY;
	int tempDay = 1;
	int allDays = days;
	System.out.println(allDays);
		
	for(int i = 0; i < allDays; i++) {
			
		tempDay++;
			
		if(tempDay > getDaysOfMonth(tempMonth)) {
			tempMonth++;
			tempDay = 1;
		}
			
		if(tempMonth > MAXMONTHSOFYEAR) {
			tempYear++;
			tempMonth = 1;
		}
	}
		
	this.setYear(tempYear);
	this.setMonth(tempMonth);
	this.setDay(tempDay);
}

Die Konstante JANUARY ist natürlich 1. Das Datum im allgemeinen meines Wissens
nach der Tag, seit dem die Millisekunden gezählt werden (?!).
MAXMONTHSOFYEAR ist natürlich 12.
(btw. fällt jemanden hierzu ein besseren Methoden-Namen ein? 😉)

Die Methode getDaysOfMonth() sieht so aus:

Java:
public int getDaysOfMonth(int month) {
	if(month == JANUARY) {
		return 31;
	} else if(month == FEBRUARY) {
		if(isLeapYear(year)) {
			return 29;
		} else {
			return 28;
		}
	} else if(month == MARCH) {
		return 31;
	} else if(month == APRIL) {
		return 30;
	} else if(month == MAY) {
		return 31;
	} else if(month == JUNE) {
		return 30;
	} else if(month == JULY) {
		return 31;
	} else if(month == AUGUST) {
		return 31;
	} else if(month == SEPTEMBER) {
		return 30;
	} else if(month == OCTOBER) {
		return 31;
	} else if(month == NOVEMBER) {
		return 30;
	} else if(month == DECEMBER) {
		return 31;
	} else {
		return -1;
	}
}

Die Konstanten brauche ich denke ich nicht weiter erläutern 😉

Und zu guter letzt die isLeapYear():

Java:
public boolean isLeapYear(int year) {
	if(year%4 == 0) {
		if(year%100 == 0) {
			if(year%400 == 0) {
				return true;
			} else {
				return false;
			}
		}
		return true;
	}
	return false;
}

Für das heutige Datum müsste demnach ja 20.03.2012 rauskommen.
Es kommt allerdings der 17.01.2012 raus, also stimmt da iwo was nicht
aber ich komm einfach nicht drauf.

Hat jemand eventuell einen Tipp für mich? 😉
 
> tempMonth = 1;
im Code ist nicht sehr professionell, wenn schon Konstanten angelegt sind,

diese Konstanten und sonstige fehlende Methoden NICHT zu posten ist übrigens ziemlich gemein,
wie soll man das testen, nur durch Anschauen auf die Lösung kommen? 😉

der Fehler ist anscheinend
> if(isLeapYear(year))
in getDaysOfMonth(), was ist dort year? wohl nicht tempYear aus der Schleife, sondern mutmaßlich das aktuelle Jahr 2012,
dann ist jedes Jahr Schaltjahr, das passt zu den fehlenden Tagen, denke ich

solche Sachen sind doch ideale Testfälle, schade dass du darauf verzichtest,
fange mit 1.1.1970 an, funktioniert das? danach 1 Tag, 5 Tage, 25 Tage, 35 Tage usw. nach vorne springen wo tritt erstmals ein Fehler auf,
im Detail anschauen welche Monatswerte usw. zusammenaddiert werden


-1 bei unbekannten Monat solltest du nicht zurückgeben, so kann ein weiterer möglicher Fehler unerkannt bleiben,
wirf eine Exception!

@AlexSpritze
die Calendar-Implementierung von Java wird oftmals aber gerade nicht als natürlich angesehen 😉

Java:
public class Test
{

    public static void main(String[] args)
    {
        new Test();
    }

    public Test()
    {
       long time = System.currentTimeMillis();
        long temp = time;

//        this.setMilliSecond((int)(temp % 1000));
        temp /= 1000;
//        this.setSecond((int)(temp % 60));
        temp /= 60;
//        this.setMinute((int)(temp % 60));
        temp /= 60;
//        this.setHour((int)(temp % 24));
        temp /= 24;

        setYearMonthDay((int)temp);
    }

    private void setYearMonthDay(int days)
    {
        int tempYear = 1970;
        int tempMonth = 1;
        int tempDay = 1;
        int allDays = days;
        System.out.println(allDays);

        for (int i = 0; i < allDays; i++)
        {

            tempDay++;

            if (tempDay > getDaysOfMonth(tempMonth,tempYear))
            {
                tempMonth++;
                tempDay = 1;
            }

            if (tempMonth > 12)
            {
                tempYear++;
                tempMonth = 1;
            }
        }
        System.out.println(tempDay+"."+tempMonth+"."+tempYear);
    }

    public int getDaysOfMonth(int month, int year)
    {
        if (month == 1)
        {
            return 31;
        }
        else if (month == 2)
        {
            if (isLeapYear(year))
            {
                return 29;
            }
            else
            {
                return 28;
            }
        }
        else if (month == 3)
        {
            return 31;
        }
        else if (month == 4)
        {
            return 30;
        }
        else if (month == 5)
        {
            return 31;
        }
        else if (month == 6)
        {
            return 30;
        }
        else if (month == 7)
        {
            return 31;
        }
        else if (month == 8)
        {
            return 31;
        }
        else if (month == 9)
        {
            return 30;
        }
        else if (month == 10)
        {
            return 31;
        }
        else if (month == 11)
        {
            return 30;
        }
        else if (month == 12)
        {
            return 31;
        }
        else
        {
            throw new RuntimeException();
        }
    }


    public boolean isLeapYear(int year)
    {
        if (year % 4 == 0)
        {
            if (year % 100 == 0)
            {
                if (year % 400 == 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
}
 
Zuletzt bearbeitet von einem Moderator:
Ich hab auch eine eigene Datumsklasse geschrieben, weil mir die vorhandenen Geschmacksrichtungen nicht gefielen. Das ist nichts verwerfliches. Allerdings gehört zu meiner ein ausführlicher Unit-Test. Das finde ich sehr praktisch und gibt ein sichereres Gefühl als nur ein paar händische Tests absolviert zu haben.

Das würde ich dir auch empfehlen, solange das ganze nicht nur eine Fingerübung werden soll.
 
Ich bin ganz ehrlich, habe noch nie einen Unit-Test gemacht und war bisher immer
zu faul mich in ein neues Tool einzuarbeiten aber ihr habt natürlich Recht, das sollte
ich jetzt wirklich mal tun.

@SlaterB
Danke dir, natürlich wie ichs mir gedacht habe nen ganz einfacher Fehler.

Java:
private void setYearMonthDay(int days) {
    int tempYear = 1970;
    int tempMonth = JANUARY;
    int tempDay = 1;
    int allDays = days;
    System.out.println(allDays);
        
     this.setYear(tempYear);     // Einfach nur das hier rein ;)

    for(int i = 0; i < allDays; i++) {
            
        tempDay++;
            
        if(tempDay > getDaysOfMonth(tempMonth)) {
            tempMonth++;
            tempDay = 1;
        }
            
        if(tempMonth > MAXMONTHSOFYEAR) {
            tempYear++;
            this.setYear(tempYear);     // Einfach nur das hier rein ;)
            tempMonth = 1;
        }
    }
        
    this.setYear(tempYear);
    this.setMonth(tempMonth);
    this.setDay(tempDay);
}
 
Zuletzt bearbeitet:
Meine Meinung dazu ist, dass es ganz aufs Anwendungsgebiet ankommt.
Wenn man nur für sich privat das macht ist das doch Okay, allerdings
ist es unpassend wenn man das für commerzielle Software nutzt oder
sogar in einem Team denn:

>> STANDARTS! <<

sorgen für wiederverwendbare, saubere und wartbare Software.
 
Meine Meinung dazu ist, dass es ganz aufs Anwendungsgebiet ankommt.
Wenn man nur für sich privat das macht ist das doch Okay,

Ok, aber dann ist es eine "Fingerübung" .... und ob die nun sauber Unit-getestet sind oder nicht ... who cares.

Allerdings fallen die Unit-Test bei TDD ja nebenbei mit ab
 

Zurück
Oben