Tage berechnen

Hier mein Groovy Code. Datum wird mit einem Regex geprüft.

Code:
Integer daysInMonth(Integer month, Integer year) {
   switch(month) {
      case 1: return 31
      case 2: return 28 + (isLeapYear(year) ? 1 : 0)
      case 3: return 31
      case 4: return 30
      case 5: return 31
      case 6: return 30
      case 7: return 31
      case 8: return 31
      case 9: return 30
      case 10: return 31
      case 11: return 30
      case 12: return 31
   }
}

Boolean isLeapYear(Integer year) {
   
   boolean leap = false
   if (year % 4   == 0) leap = true
   if (year % 100 == 0) leap = false
   if (year % 400 == 0) leap = true
   return leap
}      

Integer dayNumber(String date) {
   // datum parsen und pruefen
   assert (date ==~ /\d\d\.\d\d.\d\d\d\d/)
   String[] parts = date.split("\\.")
   Integer d = parts[0].toInteger()
   Integer m = parts[1].toInteger()
   Integer y = parts[2].toInteger()
   assert (1 <= m && m <= 12)
   assert (1 <= d && d <= daysInMonth(m, y))
   
   // summe bilden
   Integer days = 0
   for (i in 1..<m)
      days += daysInMonth(i, y)
   days += d
   return days
}

println dayNumber("12.08.2005")  // 224
println dayNumber("01.01.2000")  // 1
println dayNumber("01.02.2000")  // 32
println dayNumber("29.02.2000")  // 60
 
Tage Berechnen

Ich habe eine Lösung für das Berechnen der Tage in C# mit Benutzeroberfläche erstellt.
Ich verwende dafür zwei Textboxen tbEingabeDatum (für die Eingabe des Datums) und tbAusgabeTage (für die Ausgabe der Anzahl der Tage bis zum Datum)
Und einen Button bBerechnen (für das Starten zum Berechnen der Tage).

Hier der Sourcecode, anschliessend habe ich noch das fertige Programm hinzugefügt!

Code:
 int[] jahr = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int[] schaltjahr = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        
        public Form1()
        {
            InitializeComponent();
        }

        private void bBerechnen_Click(object sender, EventArgs e)
        {
            string datum = tbEingabeDatum.Text;
            //tbAusgabeTage.Text = "" + datum;
            try
            {
                int tag = Convert.ToInt16(datum.Substring(0, 2));
                int monat = Convert.ToInt16(datum.Substring(3, 2));
                int year = Convert.ToInt16(datum.Substring(6, 4));
                int SummeTage = 0;
                if (year % 4 == 0)
                {
                    if (kontrolleSchaltjahr(tag, monat) == true)
                    {
                        for (int i = 0; i < monat - 1; i++)
                        {
                            SummeTage = SummeTage + schaltjahr[i];
                        }
                        SummeTage = SummeTage + tag - 1;
                    }
                }
                else
                {
                    if (kontrolleJahr(tag, monat) == true)
                    {
                        for (int i = 0; i < monat - 1; i++)
                        {
                            SummeTage = SummeTage + jahr[i];
                        }
                        SummeTage = SummeTage + tag - 1;
                    }
                }
                tbAusgabeTage.Text = "" + SummeTage;
            }
            catch
            {
            }
        }

        private Boolean kontrolleJahr(int tag, int monat)
        {
            if (monat <= 12 && monat != 0)
            {
                if (tag <= jahr[monat - 1] && tag != 0)
                {
                    return true;
                }
            }
            return false;
        }

        private Boolean kontrolleSchaltjahr(int tag, int monat)
        {
            if (monat <= 12 && monat != 0)
            {
                if (tag <= schaltjahr[monat - 1] && tag != 0)
                {
                    return true;
                }
            }
            return false;
        }

War eine wirklich tolle aufgabe
Mfg David
 
ist zwar bisschen gemogelt, aber geht auch:
Code:
<?php
echo (strtotime("14 March 2007")-strtotime("1 January 2000"))/86400;
?>
 
der code stimmt nicht hunderprozentig mit der aufgabenstellung überein da die aufgabenstellung aus meinem tollen c/c++ buch nur wissen möchte der wievielte tag des jahres es ist. also stimmt nur die ausgabe nicht ganz

also hier meine c version ^^

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

main()
{
      int jan, feb, mar, apr, may, jun, jul, aug, sep, okt, nov, dez; 
      int schalt;                                               
      
      jan = 31;                             
      nov = sep = jul = may = mar = jan;
      
      apr = 30;                             
      dez = okt = aug = jun = apr;
      
      feb = 28;                             
      
      int day, month, year;                  
      int dayofyear;                      
      
      printf("Datum (dd.mm.YYYY): ");        
      scanf("%d.%d.%d", &day, &month, &year);
      printf("\n \n");
      
      if(year%4 == 0)
      {
                if(year%100 != 0)
                {
                            if(year%400 == 0)
                            {
                                        schalt = 1;
                            }
                            else
                                schalt = 0;
                }
                else
                    schalt = 0;
      }
      else
          schalt = 0;
          
      if(schalt == 1)
               feb = feb + 1;
      
      if(month == 1)                     
               dayofyear = day;
      
      if(month == 2)
               dayofyear = jan + day;
      
      if(month == 3)
               dayofyear = jan + feb + day;
               
      if(month == 4)
               dayofyear = jan + feb + mar + day;
               
      if(month == 5)
               dayofyear = jan + feb + mar + apr + day;
      
      if(month == 6)
               dayofyear = jan + feb + mar + apr + may + day;
      
      if(month == 7)
               dayofyear = jan + feb + mar + apr + may + jun + day;
               
      if(month == 8)
               dayofyear = jan + feb + mar + apr + may + jun + jul + day;
      
      if(month == 9)
               dayofyear = jan + feb + mar + apr + may + jun + jul + aug + day;

      if(month == 10)
               dayofyear = jan + feb + mar + apr + may + jun + jul + aug + sep + day;
      
      if(month == 11)
               dayofyear = jan + feb + mar + apr + may + jun + jul + aug + sep + okt + day;
               
      if(month == 12)
               dayofyear = jan + feb + mar + apr + may + jun + jul + aug + sep + okt + nov + day;
      
      printf("der %d.%d.%d ist der %d. tag des Jahres\n", day, month, year, dayofyear);
      printf("EoF");


}

ich weiss, is zu lang und nicht optimal gelöst aber ich bin ja auch noch anfänger ;-)

mfg
rusty

edit// ach ja ob das eigentlich datum überhaupt richtig ist überprüft der code übrigens nicht ^^
 
Jop, da hast du sogar Recht ;)

so müsste es hinkommen:
Code:
if(year%4 == 0)
{
    if(year%100 != 0)
    {
        schalt = 1;
    }
    else
    {
        if(year%400 == 0)
        {
            schalt = 1;
        }
        else
        {
            schalt = 0;
        }
    }
}
else
    schalt = 0;
    .
    .
    .
 
mein lösung in PVX

Code:
JANU=31
FEBR=28
MARZ=31
APRI=30
MAI=31
JUNI=30
JULI=31
AUGU=31
SEPT=30
OKTO=31
NOVE=30
DEZE=31

PRINT "Geben Sie ihr Zieldatum ein."
PRINT "Bitte beachten Sie das Sie ein g",CHR(252),"ltiges Datum eingeben,"
PRINT "mit der Formatirung DD.MM.YYYY"
INPUT "Eingabe: ",DATUME$

RECHNUNG=0
TAGJ=01
MONATJ=01
JAHRJ=NUM(DATUME$(7,4))
TAGE=NUM(DATUME$(1,2))
MONATE=NUM(DATUME$(4,2))
JAHRE=NUM(DATUME$(7,4))

IF MOD(JAHRE,4)=0 AND MOD(JAHRE,100)<>0 THEN {
	FEBR=FEBR+1
} ELSE IF MOD(JAHRE,400)=0 THEN {
	FEBR=FEBR+1
}

SWITCH (MONATE)
CASE 12
IF TAGE>DEZE OR TAGE<1 THEN MONATE=41
RECHNUNG+=NOVE
CASE 11
IF TAGE>NOVE OR TAGE<1 THEN MONATE=41
RECHNUNG+=OKTO
CASE 10
IF TAGE>OKTO OR TAGE<1 THEN MONATE=41
RECHNUNG+=SEPT
CASE 09
IF TAGE>SEPT OR TAGE<1 THEN MONATE=41
RECHNUNG+=AUGU
CASE 08
IF TAGE>AUGU OR TAGE<1 THEN MONATE=41
RECHNUNG+=JULI
CASE 07
IF TAGE>JULI OR TAGE<1 THEN MONATE=41
RECHNUNG+=JUNI
CASE 06
IF TAGE>JUNI OR TAGE<1 THEN MONATE=41
RECHNUNG+=MAI
CASE 05
IF TAGE>MAI OR TAGE<1 THEN MONATE=41
RECHNUNG+=APRI
CASE 04
IF TAGE>APRI OR TAGE<1 THEN MONATE=41
RECHNUNG+=MARZ
CASE 03
IF TAGE>MARZ OR TAGE<1 THEN MONATE=41
RECHNUNG+=FEBR
CASE 02
IF TAGE>FEBR OR TAGE<1 THEN MONATE=41
RECHNUNG+=JANU
CASE 01
IF TAGE>JANU OR TAGE<1 THEN MONATE=41
BREAK
DEFAULT
MONATE=41
BREAK
END SWITCH

IF MONATE=41 THEN {
	PRINT "Ihr Datum hat eine Falsche Angabe."
	PRINT "Bitte wiederholen sie das Programm."
	STOP
}

FOR I=1 TO TAGE STEP 1
RECHNUNG+=1
NEXT

PRINT "DATUM: Okay"
PRINT ""
PRINT "Zeitraum: Vom ",TAGJ,".",MONATJ,".",JAHRJ," bis ",DATUME$
PRINT "TAGE: ",RECHNUNG
 
Meine Java Lösung, etwas erweitert:

Code:
public class DatesMain {

	public static void main(String[] args) {
		Date d1 = new Date("31.08.2022"); 
		Date d2 = new Date("31.08.2000"); 
		Date d3 = new Date("31.08.1986");
		Date d4 = new Date("08.08.1988"); 

		System.out.println(d1.getStrDate() +" - "+ d2.getStrDate() +" => "+ d1.compareWith(d2));
		System.out.println(d3.getStrDate() +" - "+ d4.getStrDate() +" => "+ d3.compareWith(d4));
	}

}

Code:
public class Date {

	private String strDate;
	private int daysYears;
	
	public Date(String strDate) {
		this.strDate = validDate(strDate);
		this.init();
	}
	
	private String validDate(String strDate) {
		try {
			if(!strDate.matches("[0-3][0-9]\\.[0-1][0-9]\\.[1-9][0-9][0-9][0-9]")) {
				throw new Exception("Ungültiges Format!");
			}
		} catch(Exception ex) { System.out.println(ex.getMessage()); }
		
		return strDate;
	}
	
	private void init() {
		int[] months = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		
		int day = Integer.parseInt(strDate.split("\\.")[0]);
		int month = Integer.parseInt(strDate.split("\\.")[1]);
		int year = Integer.parseInt(strDate.split("\\.")[2]);
		
		months[1] = 28 + (isLeapYear(year) ? 1 : 0);
		daysYears += (day + 1);
		for(int pastYear=1900; pastYear<year; pastYear++) { daysYears += 365 + (isLeapYear(pastYear) ? 1 : 0); }
		for(int i=0; i<month-1; i++) { daysYears += months[i]; }
	}
	
	private boolean isLeapYear(int year) {
		return ((year%4 == 0 && year%100 != 0) || year%400 == 0);
	}
	
	public int compareWith(Date dateObj) {
		return Math.abs((daysYears - dateObj.getDaysYears()));
	}
	
	public String getStrDate() {
		return strDate;
	}
	
	public int getDaysYears() {
		return daysYears;
	}
	
}

Gruß
Felix
 
Hier eine Lösung in VB.

Ist länger geworden, als ich dachte...gibt bestimmt noch Optimierungsmöglichkeiten - aber es funktioniert.

Allerdings habe ich zu der angegebenen Berechnung im ersten Post einen Unterschied von einem Tag (223 statt 224 Tage zwischen 1.1.2005 und 12.8.2005), was aber wahrscheinlich von der Ausgangslogik abhängt (ob man den 1.1.05 im Bsp dazu zählt oder nicht).

Es ist als Windowsanwendung geschrieben, welche einen Button "btnBerechnen" und eine Textbox "txtEin" benötigt.

Code:
Public Class Form1
    Public monate As Integer() = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    Public eTag As Integer = 0, eMonat As Integer = 0, eJahr As Integer = 0
    Public aTag As Integer = Now.Day
    Public aMonat As Integer = Now.Month
    Public aJahr As Integer = Now.Year
    Public anzahlTage As Integer = 0

    Private Sub btnBerechnen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBerechnen.Click
        WerteEinlesen()
        If MsgBox("Möchten Sie ein ""Zieldatum"" eingeben?", MsgBoxStyle.YesNo, "Zieldatum") = MsgBoxResult.Yes Then
            Dim str As String = InputBox("Bitte geben Sie Ihr gewünschtes Zieldatum ein:", "Zieldatum")
            aTag = str.Substring(0, str.IndexOf("."))
            aMonat = str.Substring((str.IndexOf(".") + 1), (str.LastIndexOf(".") - (str.IndexOf(".") + 1)))
            aJahr = str.Substring(str.LastIndexOf(".") + 1)
        End If
        If DatumKorrekt(eTag, eMonat, eJahr) = False Then
            MsgBox("Sie haben ein ungültiges Datum eingegeben - bitte überbrüfen Sie Ihre Eingabe!", MsgBoxStyle.OkOnly, "Ungültiges Datum")
            txtEin.Focus()
            txtEin.SelectAll()
            Exit Sub
        Else
            Berechnung()
            MsgBox(anzahlTage)
        End If
    End Sub

    Public Function Schaltjahr(ByVal jahr) As Boolean
        If (jahr Mod 400 = 0) Or (jahr Mod 4 = 0 And jahr Mod 100 <> 0) Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Sub WerteEinlesen()
        If txtEin.Text <> "" Then
            eTag = txtEin.Text.Substring(0, txtEin.Text.IndexOf("."))
            eMonat = txtEin.Text.Substring((txtEin.Text.IndexOf(".") + 1), (txtEin.Text.LastIndexOf(".") - (txtEin.Text.IndexOf(".") + 1)))
            eJahr = txtEin.Text.Substring(txtEin.Text.LastIndexOf(".") + 1)
            txtEin.Text = (Format(eTag, "00") & "." & Format(eMonat, "00") & "." & Format(eJahr, "0000"))
        End If
    End Sub

    Public Function DatumKorrekt(ByVal t As Integer, ByVal m As Integer, ByVal j As Integer) As Boolean
        If m > 12 Then
            Return False
        End If
        If t > 28 Then
            If m = 2 Then
                If t > 29 Then
                    Return False
                ElseIf Schaltjahr(j) = False Then
                    Return False
                End If
            ElseIf t > 30 Then
                If m = 4 Or m = 6 Or m = 9 Or m = 11 Or t > 31 Then
                    Return False
                End If
            End If
        End If
        Return True
    End Function

    Public Function Berechnung() As Integer
        'restliche Tage des angegebenen Jahres
        If eJahr < aJahr Then
            anzahlTage = monate(eMonat - 1) - eTag
            If eMonat < 12 Then
                For i As Integer = eMonat To 11
                    If i = 1 And Schaltjahr(eJahr) = True Then
                        anzahlTage += 1
                    End If
                    anzahlTage += monate(i)
                Next
            End If
        End If
        'die Jahre dazwischen - falls vorhanden
        If eJahr + 1 < aJahr Then
            For i As Integer = eJahr To aJahr - 2
                anzahlTage += 365
                If Schaltjahr(i + 1) = True Then
                    anzahlTage += 1
                End If
            Next
        End If
        'aktuelles Jahr
        If eJahr < aJahr Then
            For i As Integer = 0 To aMonat - 2
                If i = 1 And Schaltjahr(aJahr) = True Then
                    anzahlTage += 29
                Else
                    anzahlTage += monate(i)
                End If
            Next
            anzahlTage += monate(aMonat - 1) - (monate(aMonat - 1) - aTag)
        Else
            If eMonat < aMonat Then
                anzahlTage += monate(eMonat - 1) - eTag
                For i As Integer = eMonat To aMonat - 2
                    anzahlTage += monate(i)
                Next
                anzahlTage += monate(aMonat - 1) - (monate(aMonat - 1) - aTag)
            Else
                anzahlTage = aTag - eTag
            End If
        End If
    End Function

End Class
 
Ruby

Hallo zusammen

Meine Ruby Lösung darf natürlich nicht fehlen; jetzt, wo ich die halbe Nacht daran gearbeitet habe. (Ist mein erstes etwas größeres Ruby Programm.)

PS. Ich habe mir weder die Mühe gemacht, den Code möglichst kurz zu halten, noch habe ich die Eingabe auf Korrektheit geprüft.
Aber der Übergang vom Julianischen zum Gregorianischen Kalender funktioniert.

#!/usr/bin/ruby
# -*- coding: utf-8 -*-

# @autor Philipp Gressly Freimann
# 17. Feb. 2011 (Corinas Geburtstag)
#
# Aufgabe hackerboard.de + programmieraufgaben.ch
# Gegeben dd.mm.yyyy (ein Datum). Berechne die Position im Jahr:
# 1. Jan. = 1
# 31. Dez. = 365 (mit Ausnahmen)
#
# Es wird keine Prüfung gemacht, ob das Datum existiert!

# Hilfsfunktionen:

def nach15OktImJahr1582(d, m, y)
puts "greg #{d}. #{m}. #{y}"
if( 1582 != y) then return false end
if( 10 < m) then return true end
if( 10 > m) then return false end
return 15 <= d
end

def schaltJahr(y)
# julianisch:
if(y < 1582) then return 0 == y % 4 end
# gregorianisch:
return 0 == y % 400 ? true : (0 == y % 100 ? false : (0 == y % 4))
end

# Julianische Korrektur:
# Je Differenzen zum standard ägyptischen bürgerlichen
# Verwaltungsmonat mit je 30 Tagen:
# MONAT0, Jan, Feb, März, ..., Nov (Dez. unnötig)
diff30 = [-30,1,-2,1,0,1,0,1,1,0,1,0]

# Einlesen
print "DD.MM.YYYY eingeben: "
dd,mm,yy = STDIN.gets.scan(/(\d{2})\.(\d{2})\.(\d{4})/).flatten
dd = dd.to_i; mm = mm.to_i; yy = yy.to_i

if(schaltJahr(yy))
diff30[2] += 1 #Im Februar einen Tag dazuzählen
end

res = dd
# Rechne alle Monate mit 30 Tagen (+/- Korrektur) zum Datum dazu.
diff30[0..(mm.to_i-1)].each {|d| res += d + 30}

# 1582 Korrektur:
if(nach15OktImJahr1582(dd, mm, yy))
res = res - 10
end

#Ausgabe
puts "Der #{dd}. #{mm}. #{yy} ist der #{res}. Tag im Jahr."
 
Code:
[delphi]
program Project2;

{$APPTYPE CONSOLE}

var
  d, m: Byte;
  y, e: Word;
  w: Char;


const
  DayOfWeekStr: Array[0..6] of String = (
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday',
    'Sunday'
  );

function IsLeapYear(const Year: Word): Boolean;
begin
  Result := ( Year mod 4 ) = 0;
end;

function ElapsedDaysWithinAYear(const D, M: Byte; const Y: Word): Word;
var
  i: Integer;
  LeapYear: Boolean;
begin
  Result := 0;
  if not( D in [1..31] ) or not( M in [1..12] ) then
    Exit;
  LeapYear := IsLeapYear( Y );
  for i := 1 to M - 1 do
    if i mod 2 = 1 then
    begin
      if i < 8 then
        inc( Result, 31 )
      else
        inc( Result, 30 );
    end else
    if ( i = 2 ) then
    begin
      if LeapYear then
        inc( Result, 29 )
      else
        inc( Result, 28 );
    end else
      if i < 8 then
        inc( Result, 30 )
      else
        inc( Result, 31 );
  inc( Result, D );
end;

function ElapsedDays(const fromDay, fromMonth: Byte; const fromYear: Word;
  const toDay, toMonth: Byte; const toYear: Word): DWord;
var
  i: Integer;
begin
  Result := 0;
  if fromYear = toYear then
    Result := ElapsedDaysWithinAYear( toDay, toMonth, toYear ) -
      ElapsedDaysWithinAYear( fromDay, fromMonth, toYear )
  else
  begin
    for i := fromYear+1 to toYear-1 do
      inc( Result, ElapsedDaysWithinAYear( 31, 12, i ) );
    inc( Result, ElapsedDaysWithinAYear( 31, 12, fromYear ) -
      ElapsedDaysWithinAYear( fromDay, fromMonth, fromYear ) );
    inc( Result, ElapsedDaysWithinAYear( toDay, toMonth, toYear ) );
  end;
end;

function WeekCount(const Days: Word): Byte;
begin
  Result := Days div 7;
end;

function DayOfWeek(const D, M: Byte; const Y: Word): String;
var
  DaysPassedBySince1Jan1900: DWord;
begin
//  1 Jan 1900 was a Monday.
  DaysPassedBySince1Jan1900 := ElapsedDays( 1, 1, 1900, D, M, Y );
  Result := DayofWeekStr[(DaysPassedBySince1Jan1900-1) mod 7];
end;

begin
  repeat
    Writeln( 'Input: Day Month Year' );
    Readln( d, m, y );
    e := ElapsedDaysWithinAYear( d, m, y );
    if e <> 0 then
      Writeln( 'Elapsed days: ', e, ' (as weeks: ', DaysAsWeeks( e ), ')' )
    else
      Writeln( 'Error!' );
    Write( 'Again? [j/n] ' );
    Read( w );
    Writeln;
  until w <> 'j';
  readln;
end.
[/delphi]

Auszug:
Code:
Input: Day Month Year
18 02 2011
Elapsed days: 49 (as weeks: 7)
Again? [j/n]
 
Zuletzt bearbeitet:
Mein Versuch

Hier noch mein Versuch. Was ich prinzipiell anders gemacht habe, ist, dass die Methode zur Berechnung nichts mit Strings macht, also die Splittung erfolgt vorher (01.02.2000 -> []{1,2,2000}.
Die Validierung ob der Übergabeparameter korrekt ist mache ich mit nem mehr oder weniger simplen Regex. Man hätte noch weiter gehen können und überprüfen, ob das Datum als solches überhaupt existiert (wie z.B. 31.11, 29.02.2001, etc).
Die Anzahl Tage pro Monat sind in einem int-array gespeichert.


Code:
package ch.slowy.days;

public class CalculateDays {
    private static int[] amountOfDaysPerMonth;

    static {
        // I am Lazy... declare in static block
        amountOfDaysPerMonth = new int[12];
        amountOfDaysPerMonth[0] = 31;
        amountOfDaysPerMonth[1] = 28;
        amountOfDaysPerMonth[2] = 31;
        amountOfDaysPerMonth[3] = 30;
        amountOfDaysPerMonth[4] = 31;
        amountOfDaysPerMonth[5] = 30;
        amountOfDaysPerMonth[6] = 31;
        amountOfDaysPerMonth[7] = 31;
        amountOfDaysPerMonth[8] = 30;
        amountOfDaysPerMonth[9] = 31;
        amountOfDaysPerMonth[10] = 30;
        amountOfDaysPerMonth[11] = 31;
    }

    public static int calculateDays(int[] splittedDate) {
        int amountOfDays = 0;
        for (int i = 0; i < splittedDate[1] - 1; i++) {
            amountOfDays += amountOfDaysPerMonth[i];
        }
        amountOfDays += splittedDate[0];
        if (isLeapYear(splittedDate[2])) {
            amountOfDays++;
        }
        return amountOfDays;
    }

    public static boolean isValidDate(String inDate) {
        return inDate
                .matches("(0[1-9]|1[0-9]|2[0-9]|3[01])\\.(0[0-9]|1[012])\\.\\d+");
    }

    public static int[] splitDate(String arg) {
        int[] returnValue = new int[3];

        boolean errorOccured = false;

        String[] splitted = arg.split("\\.");

        // the defined date pattern has three values
        if (splitted.length != 3) {
            errorOccured = true;
        } else {
            try {
                for (int i = 0; i < returnValue.length; i++) {
                    returnValue[i] = Integer.valueOf(splitted[i]);
                }
            } catch (NumberFormatException e) {
                errorOccured = true;
            }
        }

        if (errorOccured) {
            System.out.println("Unable to split argument " + arg);
            System.exit(1);
        }

        return returnValue;

    }

    public static boolean isLeapYear(int year) {
        return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
    }
}
TestCase dazu
Code:
 package ch.slowy.days;

import junit.framework.TestCase;

public class TestCalculateDays extends TestCase {
    public void testIsLeapYear() {
        assertTrue(CalculateDays.isLeapYear(2000));
        assertFalse(CalculateDays.isLeapYear(2001));
        assertFalse(CalculateDays.isLeapYear(2002));
        assertFalse(CalculateDays.isLeapYear(2003));
        assertTrue(CalculateDays.isLeapYear(2004));
        assertFalse(CalculateDays.isLeapYear(2005));
        assertFalse(CalculateDays.isLeapYear(2006));

        assertTrue(CalculateDays.isLeapYear(2400));
        assertTrue(CalculateDays.isLeapYear(2800));
    }

    public void testIsValidDate() {
        assertTrue(CalculateDays.isValidDate("01.01.2010"));
        assertTrue(CalculateDays.isValidDate("02.01.2011"));
        assertTrue(CalculateDays.isValidDate("03.01.2012"));
        assertTrue(CalculateDays.isValidDate("04.01.1999"));
        assertTrue(CalculateDays.isValidDate("05.01.1322"));
        assertTrue(CalculateDays.isValidDate("06.01.1764"));
        assertTrue(CalculateDays.isValidDate("07.02.1955"));
        assertFalse(CalculateDays.isValidDate("32.01.1900"));
        assertFalse(CalculateDays.isValidDate("00.01.0199"));
    }
    
    public void testCalculateDays(){
        assertEquals(224, CalculateDays.calculateDays(CalculateDays.splitDate("12.08.2005")));
    }
}
 
Hier meine Variante :)
public class Datumsrechner {
class Date {
int day, month, year;
Date(String date) {
String[] split = date.split("\\.");
day = Integer.parseInt(split[0]);
month = Integer.parseInt(split[1]);
year = Integer.parseInt(split[2]);
}
}

private boolean getLeapYear(int year) {
if (year % 400 == 0) return true;
else if (year % 100 == 0) return false;
else if (year % 4 == 0) return true;
return false;
}

private int[] getDaysInYear(int year) {
return new int[] { 31, getLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
}

public boolean valid(String date) {
Date d = new Date(date);
if ((d.month >= 1 && d.month <= 12) && (d.day >= 1 && d.day <= getDaysInYear(d.year)[d.month - 1]))
return true;
return false;
}

public int countDays(String startDate, String endDate) {
if (!valid(startDate) || !valid(endDate)) return -1;
Date start = new Date(startDate);
Date end = new Date(endDate);
int sumDays = 0, year = start.year, month = start.month, day = start.day;
for (; year <= end.year; year++) {
for (; month <= 12; month++) {
for (; day <= getDaysInYear(year)[month - 1]; day++) {
sumDays++;
if (day == end.day && month == end.month && year == end.year)
return sumDays;
}
day = 1;
}
month = 1;
}
return -1;
}

public static void main(String[] args) {
Datumsrechner datum = new Datumsrechner();
String start = "01.01.2005";
String end = "12.08.2005";
System.out.println("Startdatum: " + start + " -> " + datum.valid(start));
System.out.println("Enddatum: " + end + " -> " + datum.valid(end));
System.out.println("Tage: " + datum.countDays(start, end));
}
}
 
Zuletzt bearbeitet:
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!!)

Weil der der nach dem anderen kam (weiß grad nicht, wer es war und bin zu faul nachzugucken), es nicht einsah, dass der andere eine Monat nach seinem Namen hat, der mehr Tage besaß, als der Monat des anderen. Darum haben beide 31 Tage.

Hoffe, dass ich das verständlich beschrieben habe :)
 
Hallo,
wollte mal meine lösung in assembler reinstellen (bin noch anfänger)
dieser code ist aber nicht grad "optimal" ^^
das heißt er funktioniert aber man kann ihn sicher noch verbessern ...
und er überprüft noch nicht ob man jetzt die tage also 30 oder 31 richtig
hatt ...
aber hier der code : (ist für nasm. assemblieren mit
nasm blabla.asm -fbin -o blabla.com)

org 100h
;; Procedur zum lesen von TT.MM.YYYY (nasm)
%macro Lesen 0
push bp
mov bp,sp
sub sp,28h
cmp byte [80h],11 ; 80h = wie viel eingegeben ? TT.MM.YYYY + Leerzeichen = 11
je %%genug
%%fehler:
FEHLER ; prozedur FEHLER
%%genug:
mov si,82h ; 82h = beginn von den commandozeilen argumenten (81h=Leerzeichen)
xor bx,bx
inc bx
xor al,al
%%load:
lodsb ; al =zeichenladen
cmp bx,3
jb %%kleiner3
cmp bx,3
je %%punkt1
cmp bx,6
jb %%kleiner6
cmp bx,6
je %%punkt2
cmp bx,0Bh
je %%ente
mov di,bx ; bx ist ja der conter aber bp+bx ist falsch dafür bp+di ist richtig und ....
neg di ; man braucht bp-di
mov [bp+di],al
inc bx ; counter eins erhöhen ..
jmp %%load
%%kleiner3:
mov di,bx
neg di
mov [bp+di],al
inc bx
jmp %%load
%%punkt1:
%%punkt2:
cmp al,'.'
jne %%fehler
inc bx
jmp %%load
%%kleiner6:
mov di,bx
neg di
mov [bp+di],al
inc bx
jmp %%load
%%ente: ; ende ...
;; in BCD gepackt umwandeln
;; TT
xor ax,ax
mov al,byte [bp-1] ; al=erste Ziffer
cmp al,30h ;überprüfung ob es überhaupt eine ziffer ist
jb %%fehler
cmp al,39h
ja %%fehler
and al,0fh ; die ziffer ist im ascii format : ich wandele es in normale zahl um
shl al,4 ; die erste zahl ist ja die zehnerstelle also ....

mov ah,byte [bp-2] ; ist das gleiche bloß für die einerstelle
cmp ah,30h
jb %%fehler
cmp ah,39h
ja %%fehler
and ah,0fh
or al,ah ; al=Gepackte BCD Zahl zehner und einerstelle
;; MM ; hier passiert dass gleiche nur für Monat
xor bx,bx
mov bl,byte [bp-4]
cmp bl,30h
jb %%fehler
cmp bl,39h
ja %%fehler
and bl,0fh
shl bl,4
mov bh,byte [bp-5]
cmp bh,30h
jb %%fehler
cmp bh,39h
ja %%fehler
and bh,0fh
or bl,bh
mov ah,bl ; ah=Gepackte BCD Zahl zehner und einerstelle von monat
;; JJJJ ; das gleiche für das Jahr

xor bx,bx
mov bl,byte [bp-7]
cmp bl,30h
jb %%fehler
cmp bl,39h
ja %%fehler
and bl,0fh
shl bl,4
mov bh,byte [bp-8]
cmp bh,30h
jb %%fehler
cmp bh,39h
ja %%fehler
and bh,0fh
or bl,bh
mov dh,bl


xor bx,bx
mov bl,byte [bp-9]
cmp bl,30h
jb %%fehler
cmp bl,39h
ja %%fehler
and bl,0fh
shl bl,4
mov bh,byte [bp-10]
cmp bh,30h
jb %%fehler
cmp bh,39h
ja %%fehler
and bh,0fh
or bl,bh
mov dl,bl ; hier ist das für das Jahr zuende und dann steht in dh GBCD huderter und in dl GBCD einer/zehner
mov sp,bp
pop bp
%endmacro

;; ENDE der Procedur

;; Procedur zum überprüfen ob TT<=31 und MM<=12 (Jahr ist sowiso richtig ...)
%macro Uberprufen 0 ; ich denker die prozedur ist selbsterklärend ....
push bp
mov bp,sp
sub sp,28h

cmp al,00110001b ; 31
ja %%fehler
cmp ah,00010010b ; 12
ja %%fehler

jmp %%nee
%%fehler:
FEHLER
%%nee:
mov sp,bp
pop bp
%endmacro
;; ENDE der Procedur

;; Procedur zum ausrechnen des Unterschiedes
%macro Rechnen 0
mov cl,dl ; dl (zehner einer des Jahres) nach cl
teilbar ; überprüft ob durch 4 teilbar und setet carry wenn ja und ansonsten clear carry
jc %%nuller ; wenn durch 4 teilbar
%%normal:
xor bx,bx ; da wird ergebnis gespeichert
%%schalti:
dec al ; tag um eins verkürzen (der unterschied ist ja zwischen TT und 01 und nicht 00)
mov cl,al ; al ist eine gepackte bcd zahl ...
and al,0F0h ; in al steht jetzt die zehner ..
shr al,4 ;werden zu einern gemacht also als beispiel : wird 50 zu 5 ; da ich es nach binär umwandeln muss
mov ch,al ; zehner nach ch absichern
add al,al ; al*10 ...
add al,al
add al,al
add ch,ch
add al,ch ; ...
add bl,al ; in bl steht ja dann das ergebniss drin
and cl,0Fh ; in cl jetzt einer
add bl,cl ; ...
mov ch,ah ; Monat ... gebackte BCD ...
and ah,0Fh
and ch,0F0h
shr ch,4
mov cl,ch ; ch*10 ...
add ch,ch
add ch,ch
add ch,ch
add cl,cl
add ch,cl ; ...
add ah,ch
movsx di,ah
add di,di
add bx,word [TABELLE+di] ; ... monat ...
jmp %%ente
%%nuller:
test dl,dl ;durch huntert teilbar ?
je %%hundert
cmp ah,3 ; wenn der monat kleiner ist als 3 dann ist es egal ob schaltjahr oder nicht
jb %%nee1
xor bx,bx ; wenn schaltjahr dann bx auf 1 setzten = wenn schaltjahr um eins erhöhen
inc bx
jmp %%schalti
%%nee1:
jmp %%normal
%%hundert: ; wenn durch hundert teilbar muss überprüft werden ob durch 400 teilbar wenn ja = SChaltjahr wenn nein = kein schaltjahr
mov cl,dh ; dh nach cl (dh = GBCD Hunderter da ich nur überprüfen brauche ob die hunderter durch 4 teilbar sind)
teilbar ; ...
jnc %%nichtschalt
cmp ah,3
jb %%nee1
xor bx,bx
inc bx
jmp %%schalti
%%nichtschalt:
jmp %%normal
%%ente:
%endmacro
;; ENDE der Procedur

;; Prozedur zum Ausgeben des Ergebnisses
%macro Ausgeben 0

mov ax,bx ; in ax jetzt dass ergebniss
mov cx,000ah ; mann muss immer wieder durch 10 (=0ah) teilen
xor bx,bx
xor dx,dx ; ohne gibts probleme ...
%%weita:
div cx ; in ax steht jetzt dass ergebniss und in dx der rest also beispiel: 35/10 = ax=3 dx=5
push dx ; wird alles hochgepusht dann wieder runter gepopt und später ausgegeben
xor dx,dx ; ..
inc bl ; zähler...
test ax,ax ; ergebnis 0 ?
je %%fertig ; dann aufhöhren
jmp %%weita ; ansonsten weitermachen
%%fertig:
mov dx,unterschied ; ...
mov ah,09
int 21h ; ausgeben
mov ah,02 ; um ascii zeichen in dx auszugeben
%%inter:
pop dx ; hohle letzte berechnete ziffer ...
add dx,30h ; um in ascii umzuwandeln
int 21h ; ausgeben
dec bl ; zähler eins weniger
test bl,bl
je %%jea ; wenn zähler 0 dann fertig
jmp %%inter ; ansonsten weiter
%%jea:
%endmacro
;; ENDE der Prozedur

;; Prozedur für Fehler :)
%macro FEHLER 0 ; wenn ein fehler passiert .......
mov dx,fehl
mov ah,09
int 21h
mov ax,4c00h
int 21h
%endmacro
;; ENDE der Prozedur

;; Prozedur um festzustellen ob eine BCD Zahl durch 4 teilbar ist mit cl = gepackte BCD zahl ch wird für temporäre zwecke benutzt
%macro teilbar 0
mov ch,cl
and cl,0Fh
and ch,0F0h
shr ch,4
add ch,ch
add cl,ch
add ch,ch
add ch,ch
add cl,ch
shl cl,6
test cl,cl
je %%ja
clc
jmp %%ne
%%ja:
stc
%%ne:
%endmacro
;; ENDE der Prozedur


;; Programm zum berechnen von TT.MM.YYYY undzwar der unterschied zwischen 01.01.YYYY und TT.MM.YYYY
Lesen ; lesen von TT.MM.YYYY
Uberprufen ; stimmt die eingabe ?
Rechnen ; rechne unterschied aus
Ausgeben ; gib das ergebniss aus
mov ax,4c00h ; Ende
int 21h

fehl db 0dh,0ah,"Hilfe:",0dh,0ah,"Geben sie den namen dieses Programms gefolgt von ",0dh,0ah
db "einem LEERZEICHEN UND eines Datums z.B. :",0dh,0ah
db "unter.com 25.11.1922",0dh,0ah
db "die Syntax ist dabei immer TT.MM.JJJJ",0dh,0ah
db "TT= Tag z.B. 05 MM= Monat z.B. 08 JJJJ= Jahr z.B. 1520",0dh,0ah,'$'
unterschied db "Der Unterschied in Tagen, zum 01.01 der Jahres, ist ",'$'
TABELLE: ; tabelle für monate ...
dw 0
dw 0
dw 31
dw 59
dw 90
dw 120
dw 151
dw 181
dw 212
dw 243
dw 273
dw 304
dw 334
 
In Ruby mit Validierung des Datums:

Code:
#!/usr/bin/env ruby

day, month, year = ARGV[0].split(/\./)
day = day.to_i; month = month.to_i; year = year.to_i

(year % 4 == 0 && year % 100 != 0) || year % 400 == 0 ? is_leap_year = true : is_leap_year = false
months = [31,28,31,30,31,30,31,31,30,31,30,31]

begin
  raise if (day > months[month-1] && !(is_leap_year == true && month == 2 && day == months[month-1] + 1))
  raise if (day <= 0 || month > 12 || month <= 0 || year < 0) 
rescue
  puts "Kein korrektes Datum"
  exit
end

days = 0
(month-1).times { |i| days += months[i] }
days += day

days += 1 if is_leap_year == true && month > 2

puts "Anzahl Tage: #{days}"
 
Zuletzt bearbeitet:
Einige sehr schöne Lösungen hier.
Ich habe mich auch einmal dran gesetzt und das ganze in Java und in möglichst kurz gebastelt.
Ich glaube nach der perl und ruby variante habe ich damit den dritt kürzesten 8)
Vlt. folgt noch eine Version in C

Code:
public class DaysSince {
    public static void main(String[] args) {
        if(args.length < 1){System.out.println("Usage: DD.MM.YYYY"); return;}
        int daysToMonth[] = new int[]{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};    // days to i. month
        String[] in = args[0].split("\\.");
        int date[] = new int[3];
        for (int i = 0; i < date.length; i++) date[i] = Integer.parseInt(in[i]);
        if((date[2]%4 == 0 && date[2]%100 != 0) || date[2]%400   == 0) for (int i = 2; i < date[1]; i++) daysToMonth[i]++;    //   handle leap year
        System.out.println((date[0]-1 + daysToMonth[date[1]-1]) + " days   from " + 1+"."+1+"."+date[2] + " to " +   date[0]+"."+date[1]+"."+date[2]);
    }
}

Code:
public class DaysSinceV2 {
    public static void main(String[] args) {
        int daysToMonth[] = new int[]{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};    // days to [i]. month
        int daysPerMonth[] = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if(args.length < 1){System.out.println("Usage: DD.MM.YYYY"); return;}                    // parameter check
        if(!args[0].matches("[0-9]{1,2}\\.[0-9]{1,2}\\.[0-9]{4}")){System.out.println("Invalid date."); return;}
        String[] in = args[0].split("\\.");
        int date[] = new int[3];
        for (int i = 0; i < date.length; i++) date[i] = Integer.parseInt(in[i]);                // This should never produce a NFE !?
        if(date[1] > 12){System.out.println("Invalid date."); return;}                            // check month
        if((date[2]%4 == 0 && date[2]%100 != 0) || date[2]%400 == 0){for (int i = 2; i < date[1]; i++)daysToMonth[i]++; daysPerMonth[1]++;}    // handle leap year
        if(date[0] > daysPerMonth[date[1]-1]){System.out.println("Invalid date."); return;}        // check days
        System.out.println((date[0]-1 + daysToMonth[date[1]-1]) + " days from " + 1+"."+1+"."+date[2] + " to " + date[0]+"."+date[1]+"."+date[2]);
    }
}

edit: Die Kommentare sind Englisch, die Eingabe des Datums allerdings in deutscher Schreibweise. Vlt. wird das noch geändert. ^^
 
Zuletzt bearbeitet:
Ich habe dieselbe aufgebenstellung leider sollen wir dieses Beispiel mit 3 scanner einlesen das heißt scanner1 soll den Tag einlesen, scanner2 das Monat und scanner3 das Jahr.
So das Schaltjahr kann ich schon mal berechnen! Hat auch geklappt!
Aber jetzt soll ich mit Switch-Case das Datum berechnen und vom letzten Monat runter zählen!
Ich komm nicht drauf wie ich das angehen soll!
Bitte um Hilfe!!!:confused:
 
Zurück
Oben