Discussion:
Datumsdifferenz in Jahren, Monaten, Tagen berechnen
(zu alt für eine Antwort)
Andreas Killer
2009-12-12 09:48:09 UTC
Permalink
Juhu. :-)

Mir ist da grad was in die Finger gefallen, das wollte ich Euch mal
fragen:

Um z.B. das Alter einer Person zu berechnen wird ja oft die
undokumentierte Funktion DATEDIF genannt. Gerade letztens fragte
jemand nach der Berechnung (ohne VBA) für historische Personen die vor
1900 gelebt haben.

Nun ja, dachte ich, mit VBA wäre das ein Klacks, man könnte ja die
DATEDIF in VBA nachbilden. Geht auch kein Thema, aaaaaaaaaaaber:

DATEDIF rechnet ja gar nicht richtig, wenn man es mit "md", "ym"
aufruft!???!!

Dann habe ich gesucht und gesucht, nicht viel gefunden, alle Lösungen
rechnen falsch:

A1 30.01.2004
B1 02.03.2004
C1 =DATEDIF($A1;$B1;"y")
D1 =DATEDIF($A1;$B1;"ym")
E1 =DATEDIF($A1;$B1;"md")
F1 =DATEDIFVBA($A1;$B1;"y")
G1 =DATEDIFVBA($A1;$B1;"ym")
H1 =DATEDIFVBA($A1;$B1;"md")

A2 31.07.2002
B2 26.03.2003
C2 =DATEDIF($A2;$B2;"y")
D2 =DATEDIF($A2;$B2;"ym")
E2 =DATEDIF($A2;$B2;"md")
F2 =DATEDIFVBA($A2;$B2;"y")
G2 =DATEDIFVBA($A2;$B2;"ym")
H2 =DATEDIFVBA($A2;$B2;"md")

Vom 30.01.2004 bis 02.03.2004 sind es
0 Jahre 1 Monat, 2 Tage und nicht 0 Jahre 1 Monat, 1 Tage
Vom 31.07.2002 bis 26.03.2003 sind es
1 Jahre 7 Monat, 26 Tage und nicht 1 Jahre 7 Monat, 23 Tage

Auch die Formeln auf
http://www.excelformeln.de/formeln.html?welcher=141
liefern das gleiche falsche Ergebnis.

Gibt es da eine VBA-Lösung die (für alle Excel-Versionen) richtig rechnet?

Andreas.

#Const Version = 1

Function DateDifVBA(ByVal Datum1 As Date, ByVal Datum2 As Date, _
ByVal Zeiteinheit As String) As Long
'Die DATEDIF-Funktion auch für Daten vor 1900
'Zeiteinheit:
'y Anzahl kompletter Jahre
'm Anzahl kompletter Monate
'd Anzahl der Tage
'md Unterschied in Tagen, wobei Monate und Jahre ignoriert _
werden
'ym Unterschied in Monaten, Tage und Jahre bleiben _
unberücksichtigt
'yd Unterschied in Tagen, wobei die Jahre ignoriert werden
#If Version = 1 Then
Dim I As Integer
Zeiteinheit = LCase(Left(Zeiteinheit, 2))
For I = 1 To Len(Zeiteinheit)
Select Case Mid(Zeiteinheit, I, 1)
Case "y"
DateDifVBA = DateDiff("yyyy", Datum1, Datum2, _
vbUseSystemDayOfWeek, vbUseSystem)
If Datum1 > DateSerial(Year(Datum1), Month(Datum2), _
Day(Datum2)) Then DateDifVBA = DateDifVBA - 1
Datum1 = DateSerial(Year(Datum1) + DateDifVBA, Month( _
Datum1), Day(Datum1))
Case "m"
DateDifVBA = DateDiff("m", Datum1, Datum2, _
vbUseSystemDayOfWeek, vbUseSystem)
If Datum1 > DateSerial(Year(Datum1), Month(Datum1), _
Day(Datum2)) Then DateDifVBA = DateDifVBA - 1
Datum1 = DateSerial(Year(Datum1), Month(Datum1) + _
DateDifVBA, Day(Datum1))
Case "d"
DateDifVBA = DateDiff("d", Datum1, Datum2, _
vbUseSystemDayOfWeek, vbUseSystem)
End Select
Next
#End If

#If Version = 2 Then
Dim Day1 As Integer, Day2 As Integer, Days As Integer
Dim Month1 As Integer, Month2 As Integer, Months As Integer
Dim Year1 As Integer, Year2 As Integer, Years As Integer

Date2DMY Datum1, Day1, Month1, Year1
Date2DMY Datum2, Day2, Month2, Year2

'{days first}
If Day1 > Day2 Then
Month2 = Month2 - 1
If Month2 = 0 Then
Month2 = 12
Year2 = Year2 - 1
End If
Day2 = Day2 + DaysInMonth(DateSerial(Year2, Month2, 1))
End If
Days = Day2 - Day1

'{now months and years}
If Month1 > Month2 Then
Month2 = Month2 + 12
Year2 = Year2 - 1
End If
Months = Month2 - Month1
Years = Year2 - Year1

Zeiteinheit = LCase(Left(Zeiteinheit, 2))

Select Case Zeiteinheit
Case "y"
DateDifVBA = Years
Case "m"
DateDifVBA = Years * 12 + Months
Case "d"
DateDifVBA = DateDiff("d", Datum1, Datum2, _
vbUseSystemDayOfWeek, vbUseSystem)
Case "ym"
DateDifVBA = Months
Case "md"
DateDifVBA = Days
End Select
#End If
End Function

#If Version = 2 Then
Sub Date2DMY(ByVal Datum As Date, ByRef Tag, ByRef Monat, _
ByRef Jahr)
'Wandelt ein Datum in Tag, Monat, Jahr
Tag = Day(Datum)
Monat = Month(Datum)
Jahr = Year(Datum)
End Sub

Function DaysInMonth(ByVal Datum As Date) As Integer
'Liefert die Anzahl der Tage des Monats in dem Datum liegt
DaysInMonth = Day(DateSerial(Year(Datum), Month(Datum) + 1, _
1) - 1)
End Function
#End If
Peter Schleif
2009-12-12 12:23:48 UTC
Permalink
Post by Andreas Killer
DATEDIF rechnet ja gar nicht richtig, wenn man es mit "md", "ym"
aufruft!???!!
Vom 30.01.2004 bis 02.03.2004 sind es
0 Jahre 1 Monat, 2 Tage und nicht 0 Jahre 1 Monat, 1 Tage
Weder noch. 3 wäre richtig.
Post by Andreas Killer
Vom 31.07.2002 bis 26.03.2003 sind es
1 Jahre 7 Monat, 26 Tage und nicht 1 Jahre 7 Monat, 23 Tage
Stimmt. 26 ist korrekt.
Post by Andreas Killer
Gibt es da eine VBA-Lösung die (für alle Excel-Versionen) richtig rechnet?
Kannst Du mal diese php-Lösung testen. Ist zwar extrem langsam, aber zum
Testen reicht es. Du müsstest dazu vorübergehend diese beiden php-Files
direkt nach C:\ kopieren:

http://home.arcor.de/peter.schleif/php-win.exe (24 KB)
http://home.arcor.de/peter.schleif/php5ts.dll (5618 KB)

Aufruf: =phpDateDiff("md";$A1;$B1)
erlaubt: y, m, d, md

Function phpDateDiff(interval As String,d1 As Date, d2 As Date)
Static wsh As Object
Dim exe As Object
Dim cmd As String
Dim arr As Variant

Const php = "C:\php-win.exe"

cmd = cmd & "date_default_timezone_set('Europe/Berlin');"
cmd = cmd & "$date = new DateTime('" _
& Format(d2, "YYYY-MM-DD") & "');"
cmd = cmd & "$d = $date->diff(new DateTime('" _
& Format(d1, "YYYY-MM-DD") & "'));"
cmd = cmd & "echo $d->y.'|'.$d->m.'|'.$d->d.'|'.$d->days;"

If wsh Is Nothing Then Set wsh = CreateObject("WScript.Shell")
Set exe = wsh.Exec(php & " -r """ & cmd & """")

arr = Split(exe.StdOut.ReadAll & " ", "|")

If UBound(arr) <> 3 Then
phpDateDiff = "#PHPDATEDIFF!"
Else
Select Case LCase(interval)
Case "y": phpDateDiff = Val(arr(0))
Case "m": phpDateDiff = Val(arr(1))
Case "d": phpDateDiff = Val(arr(2))
Case "md": phpDateDiff = Val(arr(3))
End Select
End If

Set exe = Nothing
End Function
Martin Hentrich
2009-12-12 16:34:38 UTC
Permalink
On Sat, 12 Dec 2009 13:23:48 +0100, Peter Schleif
Post by Peter Schleif
Post by Andreas Killer
Vom 30.01.2004 bis 02.03.2004 sind es
0 Jahre 1 Monat, 2 Tage und nicht 0 Jahre 1 Monat, 1 Tage
Weder noch. 3 wäre richtig.
Warum?

Und warum ist es überhaupt abhängig vom Schaltjahr?
vom 1.1.20xx bis zum 31.8.20xx sind es nicht immer
genau 8 Monate?

Gibt es eine eindeutige Definition für "Monat" in diesem Kontext?

Ist es nicht vom 1.1.2009 bis 31.1.2009 ein Monat
Und vom 1.2.2009 bis zum 28.2.2009 auch genau ein Monat,
ebenso vom 1.6.2009 bis zum 30.6.2009?

Martin
--
Da lief Philippus hin und hörte, daß er den Propheten Jesaja las,
und fragte: Verstehst du auch, was du liest? Er aber sprach: Wie
kann ich, wenn mich nicht jemand anleitet?
[Apost. 8, 30-31]
Claus Busch
2009-12-12 16:46:01 UTC
Permalink
Hallo Martin,
Post by Martin Hentrich
Gibt es eine eindeutige Definition für "Monat" in diesem Kontext?
Ist es nicht vom 1.1.2009 bis 31.1.2009 ein Monat
Und vom 1.2.2009 bis zum 28.2.2009 auch genau ein Monat,
ebenso vom 1.6.2009 bis zum 30.6.2009?
bei "m" sind es die *vollständigen* Monate im Zeitraum.
Bei "ym" ist es die Differenz zwischen den Monaten im Anfangsdatum und dem
Enddatum. Die Tage und Jahre der Datumswerte werden dabei ignoriert.



Mit freundlichen Grüssen
Claus Busch
--
Win XP PRof SP2 / Vista Ultimate SP2
Office 2003 SP2 /2007 Ultimate SP2
Peter Schleif
2009-12-12 17:02:59 UTC
Permalink
Post by Martin Hentrich
On Sat, 12 Dec 2009 13:23:48 +0100, Peter Schleif
Post by Peter Schleif
Post by Andreas Killer
Vom 30.01.2004 bis 02.03.2004 sind es
0 Jahre 1 Monat, 2 Tage und nicht 0 Jahre 1 Monat, 1 Tage
Weder noch. 3 wäre richtig.
Warum?
Meiner Meinung macht es Sinn, von kleinerem zum größeren Datum zu gehen
und dabei zuerst die Tage, dann die Monate, dann die Jahre hochzuzählen
bis man jeweils Gleichstand mit dem zugehörigen Wert des größeren Datums
erreicht hat. Für die "30.01.2004" / "02.03.2004" bedeutet das:

30.01.2004 Start für Tag-Angleich
31.01.2004 1 Tag
01.02.2204 2 Tage
02.02.2004 3 Tage -> Gleichstand bei den Tagen erreicht.

02.02.2004 Start für Monats-Angleich
02.03.2004 1 Monat -> Gleichstand bei den Monaten erreicht.

02.03.2004 Start für Jahres-Angleich.
Nichts zu tun. -> Gleichstand bei den Jahren erreicht.

Macht zusammen: 0/1/3. Das deckt sich auch mit dem Ergebnis in PHP, dem
ich in diesem Fall mehr traue als einer (tatsächlich undokumentierten?)
Excel/VBA-Funktion - sorry.

Aber es gibt sicherlich andere Algorithmen, die zu anderen Ergebnissen
kommen. Vielleicht liegt ja genau da die Problematik.
Post by Martin Hentrich
vom 1.1.20xx bis zum 31.8.20xx sind es nicht immer
genau 8 Monate?
Nein. 7 Monate und 30 Tage
Post by Martin Hentrich
Ist es nicht vom 1.1.2009 bis 31.1.2009 ein Monat
Nein. 0 Monate 30 Tage
Post by Martin Hentrich
Und vom 1.2.2009 bis zum 28.2.2009 auch genau ein Monat,
Nein. 0 Monate 27 Tage
Post by Martin Hentrich
ebenso vom 1.6.2009 bis zum 30.6.2009?
Nein. 0 Monate 29 Tage


Peter
Claus Busch
2009-12-12 17:10:15 UTC
Permalink
Hallo Peter,
Post by Peter Schleif
Macht zusammen: 0/1/3. Das deckt sich auch mit dem Ergebnis in PHP, dem
ich in diesem Fall mehr traue als einer (tatsächlich undokumentierten?)
Excel/VBA-Funktion - sorry.
seit xl2000 ist DateDif in der Online-Hilfe dokumentiert. Allerdings sind
für die Zeiteinheiten falsche Argumente angegeben.


Mit freundlichen Grüssen
Claus Busch
--
Win XP PRof SP2 / Vista Ultimate SP2
Office 2003 SP2 /2007 Ultimate SP2
Martin Hentrich
2009-12-12 17:23:42 UTC
Permalink
On Sat, 12 Dec 2009 18:02:59 +0100, Peter Schleif
Post by Peter Schleif
Post by Martin Hentrich
vom 1.1.20xx bis zum 31.8.20xx sind es nicht immer
genau 8 Monate?
Nein. 7 Monate und 30 Tage
Und sind sind dann
vom 1.1.20xx bis zum 1.9.20xx sind es dann aber immer
genau 8 Monate? Schaltjahr hin oder her?
Post by Peter Schleif
Post by Martin Hentrich
Ist es nicht vom 1.1.2009 bis 31.1.2009 ein Monat
Nein. 0 Monate 30 Tage
Aha. Dann ist ein Tag mehr = 31 Tage aber ein Monat:
Vom 1.1.2009 bis 1.2.2009 ein Monat
Post by Peter Schleif
Post by Martin Hentrich
Und vom 1.2.2009 bis zum 28.2.2009 auch genau ein Monat,
Nein. 0 Monate 27 Tage
Aha. Dann ist ein Tag mehr = 28 Tage auch ein Monat:
Vom 1.2.2009 bis 1.3.2009 ein Monat, Schaltjahrunabhängig.
Post by Peter Schleif
Post by Martin Hentrich
ebenso vom 1.6.2009 bis zum 30.6.2009?
Nein. 0 Monate 29 Tage
Aha. Dann ist ein Tag mehr = 30 Tage aber ein Monat:
Vom 1.6.2009 bis 1.7.2009 ein Monat

Jetzt ist es mir mit deiner Erläuterung klarer. Der Monatsbegriff
kommt also vom "Zählmonat" und Schaltjahre sollten keine Rolle
spielen, wenn der Differenzzeitraum mehr als ein Monat beträgt. Bei
Differenzen unter einem Monat, bei denen der 29.2. dazwischen liegt,
spielt das Schaltjahr sehr wohl eine Rolle, aber eben nur dann. Dies
trifft auch auf Differenzen unterb einem Monat mit einem Monatswechsel
dazwischen zu.

Martin
--
Da lief Philippus hin und hörte, daß er den Propheten Jesaja las,
und fragte: Verstehst du auch, was du liest? Er aber sprach: Wie
kann ich, wenn mich nicht jemand anleitet?
[Apost. 8, 30-31]
Peter Schleif
2009-12-12 17:52:03 UTC
Permalink
Post by Martin Hentrich
vom 1.1.20xx bis zum 1.9.20xx sind es dann aber immer
genau 8 Monate? Schaltjahr hin oder her?
Vom 1.1.2009 bis 1.2.2009 ein Monat
Vom 1.2.2009 bis 1.3.2009 ein Monat, Schaltjahrunabhängig.
Vom 1.6.2009 bis 1.7.2009 ein Monat
Meiner Meinung nach korrekt. Aber, wie gesagt, kann das durch andere
Algorithmen auch anders aussehen. Ich finde es so richtig.
Post by Martin Hentrich
[...] Bei
Differenzen unter einem Monat, bei denen der 29.2. dazwischen liegt,
spielt das Schaltjahr sehr wohl eine Rolle, aber eben nur dann.
Nicht nur dann. Auch bei Differenzen _über_ einem Monat, wenn der Tag
des kleineren Datums im Februar liegt und dieser Tag größer ist als der
Tag des größeren Datums. Dann kommt man beim Hochzählen der Tage
zwangsläufig am 29.Februar vorbei und muss diesen natürlich mitzählen.

Peter
Andreas Killer
2009-12-13 09:47:13 UTC
Permalink
Post by Peter Schleif
Meiner Meinung nach korrekt. Aber, wie gesagt, kann das durch andere
Algorithmen auch anders aussehen. Ich finde es so richtig.
Ich finde Du hast hier eine klare, nachvollziehbare Logik, ganz
Klasse! Ich kann mich dem nur anschließen.
Post by Peter Schleif
Post by Martin Hentrich
[...] Bei
Differenzen unter einem Monat, bei denen der 29.2. dazwischen liegt,
spielt das Schaltjahr sehr wohl eine Rolle, aber eben nur dann.
Nicht nur dann. Auch bei Differenzen _über_ einem Monat, wenn der Tag
des kleineren Datums im Februar liegt und dieser Tag größer ist als der
Tag des größeren Datums. Dann kommt man beim Hochzählen der Tage
zwangsläufig am 29.Februar vorbei und muss diesen natürlich mitzählen.
Okay, dann müssen wir jetzt eigentlich nur noch eines klären:

Sind es vom 29.02.2000 zum 28.02.2003 nun genau 3 Jahre?

Ich denke ja, Deiner Logik folgend auch ja.
phpDateDiff liefert hier jedoch 2 Jahre 11 Monate 28 Tage.

Und vom 31.12.2003 bis 30.04.2005 müssten es 1 Jahr und 4 Monate sein?
Und vom 30.01.2004 bis 29.02.2008 müssten es 4 Jahre und 1 Monat sein?

Andreas.
Peter Schleif
2009-12-13 10:31:15 UTC
Permalink
Post by Andreas Killer
Sind es vom 29.02.2000 zum 28.02.2003 nun genau 3 Jahre?
2/11/28
Post by Andreas Killer
Ich denke ja, Deiner Logik folgend auch ja.
Neeeee. Siehe Text unten.
Post by Andreas Killer
phpDateDiff liefert hier jedoch 2 Jahre 11 Monate 28 Tage.
Meiner Meinung nach liegt PHP hier richtig.
Post by Andreas Killer
Und vom 31.12.2003 bis 30.04.2005 müssten es 1 Jahr und 4 Monate sein?
1/3/30
Post by Andreas Killer
Und vom 30.01.2004 bis 29.02.2008 müssten es 4 Jahre und 1 Monat sein?
4/0/30. PHP liefert hier noch was anderes: 4/1/1


"Mein" Algorithmus vergleicht zuerst den Tag des kleineren Datum mit dem
Tag des des größeren Datums. Ist der kleinereTag <= größererTag so wird
einfach die Differenz berechnet. Ist er aber größer, so muss der
kleinere Tag bis zum größeren hochgezählt werden; über das Monatsende
hinweg und unter Berücksichtigung der individuellen Anzahl der Tage des
kleineren Monats. Der Monat des kleineren Tages erhöht sich dadurch
natürlich auch um 1 und das Jahr auch, falls der kleinere Monat Dezember
war. Darauf basierend werden dann die Differenzen für Monat und Jahr
gebildet.

Vielleicht schaffe ich es heute noch eine VBA-Funktion zu programmieren.
Hier schon mal ein Ansatz:

If d1 > d2 Then
swap = d1
d1 = d2
d2 = swap
End If

If Day(d1) <= Day(d2) Then
anzahl_tage = Day(d2) - Day(d1)
Else
'/Bemerkung Month() funktioniert auch mit 13 Monaten/
anzahl_tage = DateSerial(Year(d1),Month(d1)+1,Day(d2)) - d1
End If

Peter
Andreas Killer
2009-12-13 18:30:05 UTC
Permalink
Post by Peter Schleif
Post by Andreas Killer
Sind es vom 29.02.2000 zum 28.02.2003 nun genau 3 Jahre?
2/11/28
Post by Andreas Killer
Ich denke ja, Deiner Logik folgend auch ja.
Neeeee. Siehe Text unten.
Der Text liefert aber keine Logik. Ich sage mal dies:

Wenn vom 1. dieses Monats bis zum 1. des nächsten Monats oder
vom 15. bis zum 15. des nächsten Monats genau 1 Monat und 0 Tage
vergangen sind, dann muss vom Ende dieses Monats bis zum Ende des
nächsten Monats auch genau 1 Monat und 0 Tage vergangen sein und nicht
0 Monate und 30, 28 oder 29 Tage.
Post by Peter Schleif
Vielleicht schaffe ich es heute noch eine VBA-Funktion zu programmieren.
Hab ich schon (noch Beta-Version), vielen Dank.

Andreas.

Function ADateDif(ByVal Datum1 As Date, ByVal Datum2 As Date, _
ByVal Zeiteinheit As String) As Long
'Die DATEDIF-Funktion ist fehlerhaft, diese funktioniert _
zudem auch für Daten vor 1900
'Zeiteinheit:
'y Anzahl kompletter Jahre
'm Anzahl kompletter Monate
'd Anzahl der Tage
'md Unterschied in Tagen, wobei Monate und Jahre ignoriert _
werden
'ym Unterschied in Monaten, Tage und Jahre bleiben _
unberücksichtigt
'yd Unterschied in Tagen, wobei die Jahre ignoriert werden
Dim Day1 As Integer, Day2 As Integer, Days As Integer
Dim Month1 As Integer, Month2 As Integer, Months As Integer
Dim Year1 As Integer, Year2 As Integer, Years As Integer
Dim Temp As Date

'Datum2 muss größer als Datum1 sein
If Datum1 > Datum2 Then
Temp = Datum1
Datum1 = Datum2
Datum2 = Temp
End If

Day1 = Day(Datum1)
Month1 = Month(Datum1)
Year1 = Year(Datum1)
Day2 = Day(Datum2)
Month2 = Month(Datum2)
Year2 = Year(Datum2)

If Day1 > Day2 Then
'Überlappt das Ende des Monats?
If Month(Datum2 + 1) <> Month2 Then
Days = 0
Else
Month1 = Month1 + 1
'Year2: den 29.Februar mitzählen!
Days = Day(DateSerial(Year2, Month1, 1) - 1) - Day1 + Day2
End If
Else
Days = Day2 - Day1
End If

If Month1 > Month2 Then
Year1 = Year1 + 1
Months = 12 - Month1 + Month2
Else
Months = Month2 - Month1
End If
Years = Year2 - Year1

Zeiteinheit = LCase(Left(Zeiteinheit, 2))
Select Case Zeiteinheit
Case "y"
ADateDif = Years
Case "m"
ADateDif = Years * 12 + Months
Case "d"
ADateDif = Datum2 - Datum1
Case "yd"
Datum2 = DateSerial(Year1, Month2, Day2)
If Datum2 > Datum1 Then
ADateDif = Datum2 - Datum1
Else
ADateDif = Datum1 - Datum2
End If
Case "ym"
ADateDif = Months
Case "md"
ADateDif = Days
End Select
End Function
Peter Schleif
2009-12-13 19:03:46 UTC
Permalink
Post by Andreas Killer
Wenn vom 1. dieses Monats bis zum 1. des nächsten Monats oder
vom 15. bis zum 15. des nächsten Monats genau 1 Monat und 0 Tage
vergangen sind, dann muss vom Ende dieses Monats bis zum Ende des
nächsten Monats auch genau 1 Monat und 0 Tage vergangen sein und nicht
0 Monate und 30, 28 oder 29 Tage.
Diese Regeln kriegst Du niemals widerspruchsfrei unter einen Hut. Ich
extrahiere aus deinem Text:

a) 1. eines Monats bis 1. des Folgemonat -> 1 Monat
b) 15. eines Monats bis 15. des Folgemonat -> 1 Monat
c) Letzter eines Monats bis Letzter des Folgemonat -> 1 Monat

Nun wende ich deine Regeln auf die folgenden vier Datenpaare an:

1. 28.02.09 - 28.03.09 -> 1 Monat (Regel a bzw. b)
2. 28.02.09 - 29.03.09 -> ???
3. 28.02.09 - 30.03.09 -> ???
4. 28.02.09 - 31.03.09 -> 1 Monat (Regel c)

Was willst Du bei 2.+3. eintragen?

Sollen alle vier Tage die gleiche Differenz bekommen?

Oder willst Du am 29.März 1 Tag draufgeben, am 30.März 2 Tage und am 31
wieder auf einen glatten Monat zurückfallen?
Post by Andreas Killer
Hab ich schon (noch Beta-Version), vielen Dank.
[...CODE ...]
Schau ich mir morgen mal an. Beste Dank.

Peter
Andreas Killer
2009-12-14 08:16:03 UTC
Permalink
Post by Peter Schleif
Diese Regeln kriegst Du niemals widerspruchsfrei unter einen Hut. Ich
a)      1. eines Monats bis      1. des Folgemonat  -> 1 Monat
b)     15. eines Monats bis     15. des Folgemonat  -> 1 Monat
c) Letzter eines Monats bis Letzter des Folgemonat  -> 1 Monat
Also für sollche komplizierte Fragen wenn ich mich immer
vertrauensvoll an meine Frau und die sagt dazu ja. :-)))

Auf der anderen Seite sagt sie aber auch das die Menschen die am 29.2.
geboren sind Ihren Geburtstag am 1.3. feiern, wenn kein Schaltjahr
ist. Gibt es hierzu eigentlich eine offizielle (staatliche) Meinnung
wie alt so jemand am 28.2. ist?
...
Post by Peter Schleif
Sollen alle vier Tage die gleiche Differenz bekommen?
Eigentlich ja, 1 Monat.

Wenn vom 1. zum 1. die Differenz genau 1 Monat ist, warum sollte die
Differenz je einen Tag davor eine andere sein? Macht für mich
irgendwie keinen Sinn.

Man müsste doch so wie AUFGELZINS mit Basis 4 (Europa 30/360) rechnen,
oder?
Fragt sich wie das diesbezüglich geht... muss ich mal drüber
nachdenken...

Andreas.
Peter Schleif
2009-12-14 17:01:01 UTC
Permalink
Post by Andreas Killer
Post by Peter Schleif
Sollen alle vier Tage die gleiche Differenz bekommen?
Eigentlich ja, 1 Monat.
Das führt dann zu der lustigen Situation, dass die Menschen für einige
Tage nicht altern. Seltsame Vorstellung. :-)

Tag der Geburt: 28.02.79

28.02.79 - 25.03.09 -> 30 Jahre, 0 Monate, 25 Tage
28.02.79 - 26.03.09 -> 30 Jahre, 0 Monate, 26 Tage
28.02.79 - 27.03.09 -> 30 Jahre, 0 Monate, 27 Tage
28.02.79 - 28.03.09 -> 30 Jahre, 1 Monat, 0 Tage
28.02.79 - 29.03.09 -> 30 Jahre, 1 Monat, 0 Tage
28.02.79 - 30.03.09 -> 30 Jahre, 1 Monat, 0 Tage
28.02.79 - 31.03.09 -> 30 Jahre, 1 Monat, 0 Tage
28.02.79 - 01.04.09 -> 30 Jahre, 1 Monat, 1 Tag
28.02.79 - 02.04.09 -> 30 Jahre, 1 Monat, 2 Tage
28.02.79 - 03.04.09 -> 30 Jahre, 1 Monat, 3 Tage


Aber mein Ansatz sieht hier auch nicht besser aus. Der würde zwar am
Monatsende weiterzählen, dafür aber am 1.April um zwei Tage
zurückspringen. Der Mensch würde also jünger! Auch seltsam.

28.02.79 - 25.03.09 -> 30 Jahre, 0 Monate, 25 Tage
28.02.79 - 26.03.09 -> 30 Jahre, 0 Monate, 26 Tage
28.02.79 - 27.03.09 -> 30 Jahre, 0 Monate, 27 Tage
28.02.79 - 28.03.09 -> 30 Jahre, 1 Monat, 0 Tage
28.02.79 - 29.03.09 -> 30 Jahre, 1 Monat, 1 Tag
28.02.79 - 30.03.09 -> 30 Jahre, 1 Monat, 2 Tage
28.02.79 - 31.03.09 -> 30 Jahre, 1 Monat, 3 Tage
28.02.79 - 01.04.09 -> 30 Jahre, 1 Monat, 1 Tag
28.02.79 - 02.04.09 -> 30 Jahre, 1 Monat, 2 Tage
28.02.79 - 03.04.09 -> 30 Jahre, 1 Monat, 3 Tage


Nun ja. Offensichtlich können wir uns nicht auf eine gemeinsame
Definition einigen. Dann macht es aber auch keinen Sinn über einen
Algorithmus zu diskutieren oder gar über dessen Implementierung. Ich
werde mich darum an dieser Stelle erstmal ausklinken, behalte das Thema
aber im Hinterkopf und werde es demnächst nochmal aufgreifen.

Weiterhin viel Erfolg.

Peter
Alexander Wolff
2009-12-13 09:04:34 UTC
Permalink
Du hast bei beiden "md"-Berechnungen hier als Spezialfall
- den Februar und das Ende vom Januar eingeschlossen,
- den März als Endmonat,
- einen Starttag >28 und
- einen Endtag kleiner als Starttag gewählt.

DATEDIF rechnet "isoliert", findet man auf diese Weise heraus: Es nimmt (bei
Endtag<Starttag) den Vormonat (=Februar) des Ende-Datums (im März) und setzt
dessen Anzahl Tage als Messlatte. Was aber interessiert uns der Vormonat zum
Endedatum? Relevant muss die Länge des Monats des Startdatums sein, wenn
Datumstag B1< Datumstag A1.

Du hast jedenfalls recht: Das ergibt hier und allgemein einen
konzeptionellen Fehler in DATEDIF.

=TAG(B1)-TAG(A1)+(TAG(B1)<TAG(A1))*TAG(DATUM(JAHR(A1);MONAT(A1)+1;))

wäre anscheinend für Datedif(...;"md") richtig. Die Formel berücksichtigt
für das Startdatum die relevante Länge des Startmonats und nicht willkürlich
die des Vormonats zum Endedatum als Messlatte. Bitte testen und Fehler
melden ;-)
--
Moin+Gruss Alexander - MVP for MS Excel - www.xxcl.de - mso2000sp3 --7-2
Alexander Wolff
2009-12-13 09:20:34 UTC
Permalink
Gestützt wird meine Vermutung durch A1: 30.3.04 und B1: 13.5.04. Auch dort
wird einfach der (kürzere) Vormonat April statt des relevanten Monats (März)
verwendet. Das gilt also auch für Enddatum in Juli, Okt und Dez, neben den
schon erörterten März und Mai.

Zur "Was ist ein Monat?"-Diskussion: Ein Monat ist letztlich eine vom
Menschen willkürlich festgelegte Distanz (wenn auch astronomisch
unterfüttert). Ein Jahr letztlich auch. So wollen wir uns bei der Ermittlung
von MD einfach an diese Konvention halten ...

http://xxcl.de/0028.htm, http://xxcl.de/0064.htm
--
Moin+Gruss Alexander - MVP for MS Excel - www.xxcl.de - mso2000sp3 --7-2
Andreas Killer
2009-12-14 18:28:50 UTC
Permalink
Post by Alexander Wolff
Du hast jedenfalls recht: Das ergibt hier und allgemein einen
konzeptionellen Fehler in DATEDIF.
Naja, irgendwas werden sich die Amis dabei wohl gedacht haben, ich
habe in anderen Quellcodes (auch in meinen alten Pascalcodes)
Berechnungen gefunden die das gleiche Ergebnis wie DATEDIF liefern.
Post by Alexander Wolff
=TAG(B1)-TAG(A1)+(TAG(B1)<TAG(A1))*TAG(DATUM(JAHR(A1);MONAT(A1)+1;))
wäre anscheinend für Datedif(...;"md") richtig. Die Formel berücksichtigt
für das Startdatum die relevante Länge des Startmonats und nicht willkürlich
die des Vormonats zum Endedatum als Messlatte. Bitte testen und Fehler
melden ;-)
Hmm ja, Du weißt ja, mit Formeln hab ich es nicht so. Und daher möchte
ich Dich als Formelexperten mal was fragen:

Könnte man nicht mit ZINSTERMTAGVA oder sowas die Differenz
ausrechnen? Ich komme da auf keinen grünen Zweig.

Gerade die Finanzmathematik-Routinen müssen oft mit der Differenz
zwischen 2 Daten rechnen, da gehe ich doch mal davon aus das die 100%
richtig rechnen, oder gibt's da bekannte Probleme?

Müsste doch irgendwie gehen, irgend eine Idee wie?

Andreas.
Alexander Wolff
2009-12-14 22:47:50 UTC
Permalink
Post by Alexander Wolff
Du hast jedenfalls recht: Das ergibt hier und allgemein einen
konzeptionellen Fehler in DATEDIF.
Naja, irgendwas werden sich die Amis dabei wohl gedacht haben, ich habe in
anderen Quellcodes (auch in meinen alten Pascalcodes) Berechnungen
gefunden die das gleiche Ergebnis wie DATEDIF liefern.
Wie sie es sich gedacht haben, habe ich erklärt: Vor-End-Monat ist für sie
maßgebend statt Startmonat. :-) Der Startmonat ist beteiligt, der
Vor-End-Monat nicht (wenn er nicht der Startmonat ist).

Meine Lösung kennt keine falsch-gleichen Ergebnisse, wenn sich das
betrachtete Intervall verändert. Sie verlagert die Problematik dorthin, wo
sie hingehört, nämlich in die sowieso nicht genau meßbare Einheit "Monat".
Könnte man nicht mit ZINSTERMTAGVA oder sowas die Differenz ausrechnen?
Ich komme da auf keinen grünen Zweig.
Finanzmathematik hat wieder eigene Fiktionen, die ich hier einfach mal
ausschließe - übrigens wieder mit dem Argument der falsch-gleichen
Ergebnisse bei Intervallveränderung.
--
Moin+Gruss Alexander - MVP for MS Excel - www.xxcl.de - mso2000sp3 --7-2
Loading...