Tage berechnen

Hallo allerseits,

für die unter euch willigen eine neue Programmieraufgabe.

Problemstellung:
Gegeben ist ein Datum vom Anwender (Eingabe: TT.MM.YYYY). Zu Berechnen sind die Tage vom 01.01.YYYY bis TT.MM.YYYY. Schwierigkeit dabei ist es, das von der jeweiligen Pattform (Programmiersprache) keine integrierten Datumsabfragen oder sonstige Utilities genutzt werden sollen.

Hinweise:
Zu beachten sind ebenfalls die Schaltjahre. Um heraus zu bekommen ob ein bestimmtes Jahr ein Schaltjahr ist, muss dieses durch 4 oder 400 Teilbar sein.

...

1582 führte daraufhin Papst Gregor den Gregorianischen Kalender ein, der das Jahr in 365 Tage, 5 Stunden, 48 Minuten und 46 Sekunden einteilt.
Nach dieser Einteilung sammelt sich ebenfalls nach
4 Jahren etwas mehr als ein ganzer Tag an, was wieder durch ein Schaltjahr fast ausgeglichen wird.
Und um die verbleibende Ungenauigkeit auszugleichen, wurde festgelegt, dass alle durch 100 teilbaren Schaltjahre ausfallen.
Nach hundert Jahren werden so schon rund 18 Stunden und 43 Minuten gut gemacht. Da man jedoch einen ganzen Tag, also 24 Stunden abzieht, müssen alle Schaltjahre, die durch 400 teilbar sind, dann doch wieder stattfinden, um diese Differenz auszugleichen.
So ist zum Beispiel das Jahr 2000, das zwar durch 100, aber auch durch 400 teilbar ist, ein Schaltjahr. Das Jahr 2100 hingegen ist nicht durch 400 teilbar und somit kein Schaltjahr.

Quelle: http://www.wdrmaus.de/sachgeschichten/archiv040229.phtml ;)

Hilfestellung:

Januar - 31 Tage
Februar - 28 Tage ( + evt. Schaltjahr )
März - 31 Tage
April - 30 Tage
Mai - 31 Tage
Juni - 30 Tage
Juli - 31 Tage
August - 31 Tage
September - 30 Tage
Oktober - 31 Tage
November - 30 Tage
Dezember - 31 Tage

Nach dem ersten Lösungsvorschlag eines anderen werde ich meine Java-Variante vorstellen.

Viel Erfolg
minzel
 
Wenn ich das richtig verstanden habe soll das ganze so ablaufen:

Eingabe: 12.08.2005
Ausgabe: Der 12.08.2005 ist ein Freitag

Oder?

Gruß, Boar
 
Jein ...

Zu Berechnen sind die Tage vom 01.01.YYYY bis TT.MM.YYYY

Beispielablauf:
////////////////////////////////////////////////

Syntax: TT.MM.YYYY
Datum: 12.08.2005 <- Hier folgt die Eingabe vom Anwender
Datum: Okay

Zeitraum: Vom 1.1.2005 bis 12.8.2005
Tage: 224

////////////////////////////////////////////////

Habe noch vergessen zu erwähnen das, dass Datum natürlich gültig sein sollte.

mfg
minzel
 
Achso, ok! Das macht die ganze Aufgabe erheblich einfacher. Werd mich am Wochenende mal dransetzen.

EDIT
So, hat ein bisschen länger gedauert.
Das Programm funktioniert soweit, die Überprüfung des eingegebenen Datums ist nur noch nicht 100% exakt. Folgende Eingaben sind im Moment erlaubt:
Syntax: TT.MM.JJJJ

0<=TT<=31, 0<=MM<=12, 1000<=JJJJ<=3000

Also könnte man z.B. auch 30.02.2005 eingeben und das Programm sagt trotzdem, dass das Datum gültig ist. Da setz ich mich bei Gelegenheit noch dran.

Das Ganze ist wie immer in Java programmiert.

Gruß, Boar
 
Nicht schlecht die Variante. Das Programm erfüllt auf jeden Fall teilweise seinen Zweck.

Hier nun meine versprochene Lösung.

Dies ist einer meiner Perversesten Java-Programme, da in der Hauptklasse keine Variablen verwendet werden, sämtliche Fehlerroutinen selber geschrieben und komplett OOP Programmiert wurde. Ebenfalls eigens geschriebene Datums-Funktionen.
Programm erfüllt alle Anforderungen der Aufgabenstellung. Sollte auch fehlerfrei sein.

Wird ein falsches (formatiertes) oder ungültiges Datum eingegeben wird unweigerlich eine Exception geworfen und das Programm bricht abrupt ab.
Bei korrekter Eingabe wird das richtige Ergebnis präsentiert.

>> printDays_Quelltext.zip

>> printDays_Execute.zip

viel vergnügen :)
minzel
 
Das Programm erfüllt auf jeden Fall teilweise seinen Zweck.
Der Satz hat mich dazu gebracht, die Datumsüberprüfung zu verbessern. Jetzt erfüllt das Programm seinen Zweck vollständig! :p

Alle falschen Datum-Eingaben führen jetzt zum Syntaxfehler. Auch Schaltjahre werden berücksichtigt. Also ist es z.B. möglich, den 29.02.2004 einzugeben, der 29.02.2003 erzeugt aber einen Syntaxfehler.

Deine Lösung gefällt mir sehr gut. Beeindruckender Quelltext!
 
sorry, der satz sollte nicht einschüchternd sein ^^

ney, aber krass, jenau so, mal schauen ob noch jemand ne lösung hat. vieleicht dann doch mal in c oder so.

minzel
 
weiß eigentlich einer von euch warum der Juli und der August beide 31 Tage haben?? *g*

Hilfestellung
Juli => Julius Cäser
August => Augustus

die Geschichten der beiden überschneiden sich. Und die überschneidung liefert die Lösung *g*

(falls der Post euch so dämlich erscheint einfach löschen!!)
 
Hinweise:
Zu beachten sind ebenfalls die Schaltjahre. Um heraus zu bekommen ob ein bestimmtes Jahr ein Schaltjahr ist, muss dieses durch 4 oder 400 Teilbar sein.

ein jahr ist ein schaltjahr wenn es durch 400 teilbar ist oder durch 4 und nicht durch 100 teilbar ist.
also in c:
Code:
if((jahr%4 == 0 && jahr%100 != 0) || jahr%400 == 0)

und jetzt meine c++ lösung. leider kann man zwischen das datum keine punkte setzen sondern nur leerzeilen.

Code:
#include <iostream>
using namespace std;

short datum_pruefen(short, short, int);
short tage_berechnen(short, short, int);

int main()
{

short tag,monat, pruefen;
int jahr, tage;

cout << "Bitte ein Datum eingeben (Syntax: TT MM YYYY, ohne Punkt!)." << endl;
cout << "Datum: ";
cin >> tag >> monat >> jahr;
cin.get();


pruefen = datum_pruefen(tag, monat, jahr);

if(pruefen == 0)
{
cout << "Falsches Datum!n";

return 0;
}

cout << "nDatum korrekt!" << endl;

tage = tage_berechnen(tag, monat, jahr);

cout << "nZeitraum vom 1.1." << jahr << " bis zum "
<< tag << "." << monat << "." << jahr << endl
<< "Tag(e): " << tage << endl;

cout << "nEnter zum beenden druecken.";


cin.get();
return 0;
}

short datum_pruefen(short tag, short monat, int jahr)
{
switch (monat)
{
case 1:
if(tag <= 31)
return 1;

return 0;
break;

case 2:
if((jahr%4 == 0 && jahr%100 != 0) || jahr%400 == 0)
{
if(tag <= 29)
return 1;
}
if(tag <= 28)
return 1;

return 0;
break;

case 3:
if(tag <= 31)
return 1;

return 0;
break;

case 4:
if(tag <= 30)
return 1;

return 0;
break;

case 5:
if(tag <= 31)
return 1;

return 0;
break;

case 6:
if(tag <= 30)
return 1;

return 0;
break;

case 7:
case 8:
if(tag <= 31)
return 1;

return 0;
break;
case 9:
if(tag <= 30)
return 1;

return 0;
break;

case 10:
if(tag <= 31)
return 1;

return 0;
break;

case 11:
if(tag <= 30)
return 1;

return 0;
break;

case 12:
if(tag <= 31)
return 1;

return 0;
break;

default:
return 0;
break;
}

return 1;
}

short tage_berechnen(short tag, short monat, int jahr)
{
short tage = 0;

short monate[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };

monat--;
for(int i=0;i<monat;i++)
tage += monate[i];
monat++;

tage += tag;

if((jahr%4 == 0 && jahr%100 != 0) || jahr%400 == 0)
tage++;

return tage;
}

man kann bestimmt einige sachen besser formulieren, bin noch c++ anfänger :(

compiliert hab ich das programm mit ms visual c++, getestet auf win xp
 
Meine Lösung ist jetzt ohne Datumsprüfung, aber die Berechnung ist ok.

Code:
#include <stdio.h>

int mon[12] =
{ /* Jan */ 0,
  /* Feb */ 31,
  /* Mar */ 31+28,
  /* Apr */ 31+28+31,
  /* Mai */ 31+28+31+30,
  /* Jun */ 31+28+31+30+31,
  /* Jul */ 31+28+31+30+31+30,
  /* Aug */ 31+28+31+30+31+30+31,
  /* Sep */ 31+28+31+30+31+30+31+31,
  /* Okt */ 31+28+31+30+31+30+31+31+30,
  /* Nov */ 31+28+31+30+31+30+31+31+30+31,
  /* Dez */ 31+28+31+30+31+30+31+31+30+31+30
};

unsigned long Get_Tage(int tag, int monat, int jahr)
{
  unsigned long tage;

  tage = jahr*365+((jahr-1)/4)-((jahr-1)/100)+((jahr-1)/400);
  tage += mon[monat-1];
  if (monat > 2)
    { if ((jahr%  4)==0) tage++;
      if ((jahr%100)==0) tage--;
      if ((jahr%400)==0) tage++;
    }
  tage += tag-1;

  return(tage);
}

int main()
{
  int geboren, heute;

  geboren = Get_Tage(18, 9, 1972);
  heute = Get_Tage(8, 9, 2005);
  printf("tage = %i\n", heute-geboren);
  return(-1);
}
 
Ich hab auch mal ne Java-Lösung geschrieben (Ich bin Java-Anfänger, deshalb ist sie bestimmt nicht optimal, Berechnung stimmt aber)

Code:
//Tagerechner.java

import java.io.*;

class Datum {
  int tag = 1;
  int monat = 1;
  int jahr = 1901;
  boolean schaltjahr = false;
  int month[] = new int[12];
  
  void getDatum() throws IOException
  {
    month[0]=31;	month[1]=28;	month[2]=31;
    month[3]=30;	month[4]=31;	month[5]=30;
    month[6]=31;	month[7]=31;	month[8]=30;
    month[9]=31;	month[10]=30;	month[11]=31;
    
    BufferedReader din = new BufferedReader(new InputStreamReader(System.in));
    do {
      System.out.println("Tag: ");
      tag = Integer.parseInt(din.readLine());
    } while (tag <= 0 || tag > 31);
    
    do {
      System.out.println("Monat (1-12): ");
      monat = Integer.parseInt(din.readLine());
      monat--;
    } while (monat < 0 || monat > 12);
    
    while (tag > month[monat] || tag <= 0) {
      System.out.println("Der eingegebene Tag ist ungültig.\nTag: ");
      tag = Integer.parseInt(din.readLine());
    }
    
    do {
      System.out.println("Jahr: ");
      jahr = Integer.parseInt(din.readLine());
    } while (jahr < 0);
  }
  
  void ifSchaltjahr()
  {
    if (jahr%400 == 0) {
      month[1] = 29;
    } else if (jahr%4 == 0 && jahr%100 != 0) {
      month[1] = 29;
    } else {
      month[1] = 28;
    }
  }
    
  void printTage()
  {
    int tage = 0;
    // Tage der Monate werden nach und nach hinzugezählt
    
    for (int i=0; i<monat; i++)
    {
      tage += month[i];
    }
    // Tage im aktiven Monat werden hinzugezählt
    tage += tag;
    // Ergebnis wird ausgegeben
    System.out.println("Zeitspanne vom 1.1." + jahr + 
                       " bis zum " + tag + "." + (monat+1) + "." + jahr + ": "
                       + tage + " Tage");
  }
}


public class Tagerechner
{
  public static void main(String[] args) throws IOException
  {
    Datum date = new Datum();
    date.getDatum();
    date.ifSchaltjahr();
    date.printTage();
  }
}
 
Hi,
dies ist mein erster Post hier im Forum.
Bin begeistert von den Programmieraufgaben und würde mir manchmal wünschen, das es mehr davon gibt.
Bis jetzt habe ich nie die Möglichkeit gefunden, mal eine zu versuchen, aber jetzt habe ich mich einfach mal hingesetzt und versucht.
Dies ist dabei rausgekommen.

Würde mich über Verbesserungsvorschläge und Tipps freuen.

Code:
import java.io.*;
import java.util.StringTokenizer;

public class PrintDays {

	// the day count of the months ( be careful with february )
	static int months[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	
	// main function
	public static void main(String[] args) {
		StringTokenizer datum = new StringTokenizer(readDatum());
		int day = Integer.valueOf(datum.nextToken(".")).intValue();
		int month = Integer.valueOf(datum.nextToken(".")).intValue();
		int year = Integer.valueOf(datum.nextToken(".")).intValue();
		
		if(datum.hasMoreElements()){
			System.out.println("Fehler bei der Eingabe, bitte nutzen Sie das angegebene Format.");
			System.exit(-1);
		}
		
		System.out.println("\nEs sind " + calculateDays(day,month,year) 
				+ " Tage seit dem 01.01." + year + " vergangen");
	}
	
	// reads the date
	public static String readDatum(){
		String input = null;
		
		System.out.println("Bitte geben Sie ein Datum ein. Format DD.MM.YYYY");
		System.out.print("> ");
		try{
			BufferedReader in = new BufferedReader( new InputStreamReader(System.in) );
			input = in.readLine();
		} catch(Exception e){
			System.out.println("Fehler bei der Eingabe");
			System.exit(-1);
		}
		return input;
	}
	
	// calculate days
	public static int calculateDays(int day, int month, int year){

		int days = 0;
		
		if( (year%4==0 && year%100!=0) || year%400==0 ){
			months[1] = 29;
		}
		
		// check if month is correct
		if(month <= 0 || month > 12){
			System.out.println("Sie haben ein ungueltiges Datum angegeben.");
			System.exit(-1);
		}
		
		// check if day is correct
		if(day > months[month-1] || day <= 0){
			System.out.println("Sie haben ein ungueltiges Datum angegeben.");
			System.exit(-1);
		}
		
		// adding days of month
		for(int i = 0; i < month-1; i++){
			days += months[i];
		}
		
		// adding days of current month
		days += day;		
		
		return days;
	}
}
 
So hier mal meine Lösung in c++

Anmerkung ich hab vor 2 tagen mit c++ begonnen also vergebt mir wenn mein kode übelst suckt ^^.

Desweiteren hab ich die ganezn kommentare auf englisch einfach weil ich nach nem englischen buch lerne "C++ for dummies" und selber englisch besser als deutsch finde :p

Also langere Rede kurzer Sinn hier meine version

Code:
#include <cstdio>
#include <cstdlib>
#include <iostream.h>

//prototype of getdays
int getdays(int days,int month,int year);

//main function
int main()
{
    cout << "Welcome to count days v0.0001 by Ancient 4 Hackerboard.de progamming challenge\n"
         << "Please enter a date in the format dd mm yyyy\n";
    int d,m,y;
    cin >> d >> m >> y;
    cout << "Thank you\n";
    if (getdays(d,m,y) > 0)
    {
    cout << "Days passed from 01.01." << y << " until " << d << "." << m << "." << y << ": " << getdays(d,m,y);
    }
    else 
    {
     cout << "Told ya an error occured";
     return 0;
    }
    return 0;
}

//real getdays function
int getdays(int days,int month,int year)
{
    //int array of months with corresponding day values
    int monarray[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    //answer variable
    int totaldays = 0;
    //check that user entries are valid
    if ((month < 13 && month > 0) && (days <= monarray[month]))
    {
     //add number of days of all full months passed at user date
     for(int i = 1 ; i < month ; i++) 
     {
            totaldays = totaldays + monarray[i];
            
     }
     //if leapyear and february included then total days incremented by 1 
     if ((year%400 == 0 || year%4 == 0) && (month > 2))
     {
               totaldays += 1;
     }
              totaldays = totaldays + days;
              return totaldays;
    }
    else 
    {
         cout << "an error has occured we will now terminate try again with real values goodbye\n" ;
         return 0;
   }
}

PS: Ich weis das es noch ein paar bugs hat und man es z.B mit eingabe des 28. in einem schaltjahr austricksen kann.
MFG Ancient.
 
Hehe 20 Zeilen ohne Datumscheck (Leerzeilen inklusive :])
Code:
#include <iostream>

int main(void)
{
int d,m,y,days = 0;
short months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

std::cout << "Datum eingeben(dd mm yyyy):\n";
std::cin  >> d >> m >> y;

for (int i = 0;  i < m-1  ;i++)
 days += months[i];

if(((y % 4) == 0 || (y % 400) == 0) && (m > 2) )
 ++days;

std::cout << "Seit dem 1.1. sind " << (days + d) << " Tage vergangen!\n";

return 0;
}
Mit Minimalcheck 23 Zeilen
Code:
#include <iostream>

int main(void)
{
int d,m,y,days = 0;
short months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

std::cout << "Datum eingeben(dd mm yyyy):\n";
std::cin  >> d >> m >> y;

if(d > months[d] || m > 12 )
 return -1;

for (int i = 0;  i < m-1  ;i++)
 days += months[i];

if(((y % 4) == 0 || (y % 400) == 0) && (m > 2) )
 ++days;

std::cout << "Seit dem 1.1. sind " << (days + d) << " Tage vergangen!\n";

return 0;
}

Wer kann mich unterbieten? :D


Xalon

P.S:Wenn mein Programm der Aufgabe nicht nachkommt (ja ich weiß 100% kommt es ihr nicht nach :p ) sagt es mir ^^
 
Kleine Anmerkung am Rande...

Wenn die Jahreszahl ohne Rest durch 400 teilbar ist, ist sie auch durch 4 teilbar. Ihr könnt Euch also eigentlich die Abfrage mit dem 'or' sparen.

Sinn macht die Abfrage nach modulo 400 aber gewissermaßen schon, denn um ganz korrekt zu sein... Jahreszahlen, die durch 100 aber nicht durch 400 teilbar sind, sind keine Schaltjahre (zu mindest im gregorianischen Kalender) - bspw. 1900, 2100, 2200, 2300 etc..

Die Abfrage müsste also lauten:

Code:
if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)

MfG
 
Original von Xalon
Wer kann mich unterbieten? :D

Code:
#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
	if( argc != 4 || atoi(argv[2])>12 )
		return -1;

	int daySum[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
	int days = atoi(argv[1]) + daySum[atoi(argv[2])-1];
	if( days > daySum[atoi(argv[2])] )
		return -1;
	
	if(((atoi(argv[3])%4 == 0 && atoi(argv[3])%100 != 0) || atoi(argv[3])%400 == 0) && atoi(argv[2]) >2)
		++days;

	cout << days << " Tage seit dem 1.1." << argv[3] << endl;
	return 0;
}
Ich. 19 Zeilen mit 'using namespace std', Leerzeilen und rudimentärem Check.
:D
Aufruf: <name> dd mm yyyy

3. + letztes edit: Ich weiß übrigens, dass der Check den 29.2. eines Schaltjahres verbietet. Aber das ist der Preis für Kürze mit Würze 8)
 
Mir war grad langweilig, da hab ich mal in die progamieraufgaben geschaut und hab die hier mal gelöst.

PHP:
<?php

//Datum was berechnet werden soll
$Datum = "17#3#2001";

$Date=split("#", $Datum);

//Schaltjahr überbrüfung
$schaltjahr=0;
if (is_int($Date[2]/4)) {
  if ((!(is_int($Date[2]/100))) || (is_int($Date[2]/400)))  {
	  $schaltjahr=1;
	}
}

$month[1] = array(31,31);
$month[2] = array(28,29);
$month[3] = array(31,31);
$month[4] = array(30,30);
$month[5] = array(31,31);
$month[6] = array(30,30);
$month[7] = array(31,31);
$month[8] = array(31,31);
$month[9] = array(30,30);
$month[10] = array(31,31);
$month[11] = array(30,30);
$month[12] = array(31,31);

$tage=0;

if ($schaltjahr==1) {
  $tage=$tage-($month[$Date[1]][1]-$Date[0]);
}
if ($schaltjahr==0) {
  $tage=$tage-($month[$Date[1]][0]-$Date[0]);
}
while ($Date[1] > 0) {
  if ($schaltjahr==1) {
	  $tage=$tage+$month[$Date[1]][1];
	}
  if ($schaltjahr==0) {
	  $tage=$tage+$month[$Date[1]][0];
	}
  $Date[1]--;
}


print $tage;
?>


EDIT:

ich hab gerade noch was weiter gemacht, und jetzt kann man auch zwei datume eingeben und er berchnet die Tage zwischen ihnen:

PHP:
<?php

//Datum:
//von:
$Datum2 = "3#12#1990";
//bis:
$Datum = "20#8#2006";

$Date=split("#", $Datum);
$Date2=split("#", $Datum2);

//Schaltjahr überbrüfung1
$schaltjahr=0;
if (is_int($Date[2]/4)) {
  if ((!(is_int($Date[2]/100))) || (is_int($Date[2]/400)))  {
	  $schaltjahr=1;
	}
}

//Schaltjahr überbrüfung2
$schaltjahr2=0;
if (is_int($Date2[2]/4)) {
  if ((!(is_int($Date2[2]/100))) || (is_int($Date2[2]/400)))  {
	  $schaltjahr2=1;
	}
}


$month[1] = array(31,31);
$month[2] = array(28,29);
$month[3] = array(31,31);
$month[4] = array(30,30);
$month[5] = array(31,31);
$month[6] = array(30,30);
$month[7] = array(31,31);
$month[8] = array(31,31);
$month[9] = array(30,30);
$month[10] = array(31,31);
$month[11] = array(30,30);
$month[12] = array(31,31);

$tage=0;

if ($schaltjahr==1) {
  $tage=$tage-($month[$Date[1]][1]-$Date[0]);
}
if ($schaltjahr==0) {
  $tage=$tage-($month[$Date[1]][0]-$Date[0]);
}
while ($Date[1] > 0) {
  if ($schaltjahr==1) {
	  $tage=$tage+$month[$Date[1]][1];
	}
  if ($schaltjahr==0) {
	  $tage=$tage+$month[$Date[1]][0];
	}
  $Date[1]--;
}

while($Date2[1] < 13) {
  if ($schaltjahr2==1) {
	  $tage=$tage+$month[$Date2[1]][1];
	}
  if ($schaltjahr2==0) {
	  $tage=$tage+$month[$Date2[1]][0];
	}
  $Date2[1]++;
}
$tage= $tage-$Date2[0];

$a=365*($Date[2]-$Date2[2]-1);
while ($Date2[2] < $Date[2]) {
  if (is_int($Date2[2]/4)) {
    if ((!(is_int($Date2[2]/100))) || (is_int($Date2[2]/400)))  {
	    $a++;
	  }
  }
  $Date2[2]++;
}
$tage= $tage+$a;

print $tage;
?>


Jon2
 
Das ganze nochmal in Perl, absichtlich so kurz wie möglich gehalten:

Code:
#!/usr/bin/perl -w
print "Berechne die Tage vom 1.1.YYYY bis zum DD.MM.YYYY.\nDatum: ";
my @date = split(/\./, <STDIN>);
my @months = qw/31 28 31 30 31 30 31 31 30 31 30 31/;
if(($date[2] % 4 == 0 && $date[2] % 100 != 0) || $date[2] % 400 == 0) {$months[1]++;}
if($date[2] < 0 || $date[1] >= 12 || $date[0] > $months[$date[1]-1]) {exit};
for(my $i=0; $i<$date[1]-1; $i++) {$days += $months[$i];}
$days += $date[0];
if($date[1] == 1) {$days--;}
print "Anzahl Tage: ",$days,"\n";

Etwas aufgeräumter:
Code:
#!/usr/bin/perl -w
print "Berechne die Tage vom 1.1.YYYY bis zum DD.MM.YYYY.\nDatum: ";

# Eingabe aufspalten
my @date = split(/\./, <STDIN>);

# Anzahl Tage der Monate
my @months = qw/31 28 31 30 31 30 31 31 30 31 30 31/;

# Schaltjahr-Regel
if(($date[2] % 4 == 0 && $date[2] % 100 != 0) || $date[2] % 400 == 0) {
    $months[1]++;
}

# Syntax-Überprüfung
if($date[2] < 0 || $date[1] >= 12 || $date[0] > $months[$date[1] - 1]) {
    print "Ungueltige Eingabe!";
    exit;
}

# Summe der Monate bilden
for(my $i=0; $i<$date[1]-1; $i++) {
    $days += $months[$i];
}

# Restliche Tage addieren
$days += $date[0];

# Wenn wir im gleichen Monat bleiben, einen Tag wieder abziehen
if($date[1] == 1) {
    $days--;
}

# Ausgabe
print "Anzahl Tage: ",$days,"\n";

Damit hab ich den Rekord: 10 Zeilen.
Wenn ich jetzt noch Syntax-Überprüfung (incl. Schaltjahrregel: Z. 6) und die extra-Regel für den Januar (Z. 9) rauslasse, dann komme ich auf sensationelle 8 Zeilen :D
Die Januar-Regel ist notwendig, da die Berechnung sonst für den Januar nicht stimmt. (1. 1. 2007 - 2. 1. 2007 = 2 Tage)
 
Original von Eydeet
Die Januar-Regel ist notwendig, da die Berechnung sonst für den Januar nicht stimmt. (1. 1. 2007 - 2. 1. 2007 = 2 Tage)
*grübel* Da kann was nicht ganz stimmen. Happy new year!

Zum Bleistift die jahresübergreifenden Datums fehlen ganz.

Code:
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

int mon[12] =
{ /* Jan */ 0,
  /* Feb */ 31,
  /* Mar */ 31+28,
  /* Apr */ 31+28+31,
  /* Mai */ 31+28+31+30,
  /* Jun */ 31+28+31+30+31,
  /* Jul */ 31+28+31+30+31+30,
  /* Aug */ 31+28+31+30+31+30+31,
  /* Sep */ 31+28+31+30+31+30+31+31,
  /* Okt */ 31+28+31+30+31+30+31+31+30,
  /* Nov */ 31+28+31+30+31+30+31+31+30+31,
  /* Dez */ 31+28+31+30+31+30+31+31+30+31+30
};

unsigned long Get_Tage(int tag, int monat, int jahr)
{
  unsigned long tage;

  tage = jahr*365+((jahr-1)/4)-((jahr-1)/100)+((jahr-1)/400);
  tage += mon[monat-1];
  if (monat > 2)
    { if ((jahr%  4)==0) tage++;
      if ((jahr%100)==0) tage--;
      if ((jahr%400)==0) tage++;
    }
  tage += tag-1;

  return tage;
}

unsigned long Get_Tage_Str(char *s)
{
  int tag   = strtol(s,   &s, 10);
  int monat = strtol(s+1, &s, 10);
  int jahr  = strtol(s+1,  0, 10);
  return Get_Tage(tag, monat, jahr);
}

long Tage_Differenz(char *frueher, char *spaeter)
{
  return Get_Tage_Str(spaeter) - Get_Tage_Str(frueher);
}

int main()
{
  printf("%i\n", Tage_Differenz("31.12.1999", "1.1.2000")); /* 1 */
  printf("%i\n", Tage_Differenz("31.12.2000", "1.1.2001")); /* 1 */
  printf("%i\n", Tage_Differenz(" 1  1 2007", "2 1 2007")); /* 1 */

  printf("%i\n", Tage_Differenz("1 1 1900", "1 1 1901")); /* %100 365 */
  printf("%i\n", Tage_Differenz("1 1 1999", "1 1 2000")); /*      365 */
  printf("%i\n", Tage_Differenz("1 1 2000", "1 1 2001")); /* %400 366 */
  printf("%i\n", Tage_Differenz("1 1 2004", "1 1 2005")); /*   %4 366 */
  getch();
  return 0;
}
 
Zurück
Oben