CirTap: Ungültiges Datum? Gibz nich...

Beitrag lesen

Hallo Gemeinde,

ich mach ja nicht viel mit JavaScript - im Grunde genommen hasse ich es auch wie die Pest und versuche möglichst ohne auszukommen. Mag sein, daß das Folgende für einige von Euch ein alter Hut ist, ich fand's jedenfalls hochinteressant, denn folgendes ist "passiert":
Als ich gerade mal wieder in Access mit Datumsberechnung herumgewerkelt habe, bin ich versehentlich auf ein "Phänomen" bei DateSerial() gestossen:
  DateSerial(1999, 13, 1)  liefert den 1.1.2000.
Keine Fehlermeldungen, nix.

<staun action="weitertest">
  DateSerial(1999, 13, -1) liefert den 30.12.1999

Gibt man nun als Tag die 0 an, erhält man immer den letzten eines Monats:
  DateSerial(1999, 3, 0)   liefert den 28.02.1999
</staunt>

Da ich das Berechnen von Datumsdifferenzen schon immer ätzend fand und speziell, das Abfangen ungültiger Datumswerte, find ich dieses Verhalten recht praktisch. Da unser heißgeliebter IE ja auch den Basisteil von VisualBasic kann, hab ich das dort auch gleich getestet und weil sich ja keiner traut VBS einzusetzen, hab ich auch gleich den JavaScript-Test gemacht - funzt. Ale Netscape-Verehrer können also auf die JS-Buttons klicken.
"Ursache" scheint die intern verwendete Serielle Zahl zu sein, zu deren "Startwert" einfach die entsprechenden Werte addiert oder subtrahiert werden. Eigentlich hätte ich da ja schon vor Jahren draufkommen können, aber was der Bauer nicht kennt... (ich mußte auch erst mit XL95 hantieren, um festzustellen, daß DateDiff "schon" in VB3 drinwar %- ...)

Irritiert hat mich nur, daß JS offenbar bei den Monaten mit 0 anfängt zu zählen, deshalb auch das -1 hinter iMonat. Ich werd bei Gelegenheit mal einen Blick in die Doku werfen und nehm das jetzt mal als von Gott gegeben hin.

Unten hab ich mal die Seite reingeklebt, für diejenigen, die das mal probieren und/oder sehen wollen. Alle Anderen, die das schon seit Jahrhunderten kennen und jetzt schmunzeln: euer Tag ist gerettet, denn: "Ein Tag ohne Lächeln ist ein verlorener Tag" :-)

Ich für meinen Teil werde erstmal verschiedene Routinen umstricken und gegen diesen Einzeiler austauschen :)

Viel Spaß
CirTap

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Untitled</title>
<STYLE><!-- BODY,P,FORM,INPUT {font: normal 12px/1.44em Verdana","Myriad","Arial","Helvetica","sans-serif";} --></STYLE>

<SCRIPT TYPE="text/vbscript" LANGUAGE="VBScript">
<!--
Sub DatumAddierenVBS(iTag, iMonat, iJahr)
  '* Da VBS intern mit seriellen Datumswerten arbeitet,
  '* wird hier einfach (ausgehend von 1.1.1900) die Anzahl
  '* Tage, Monate und Jahre errechnet. Die Angabe von
  '* ungueltigen Daten wie 31.3. ist also moeglich und
  '* liefert entsprechend den 1.3 oder 2.3, je nach Schaltjahr

MsgBox DateSerial(iJahr, iMonat, iTag), vbInformation, \_  

CStr(iTag) & "." & CStr(iMonat) & "." & CStr(iJahr)

MsgBox "Und jetzt, je nach Datum: ein Laufzeitfehler :-)" & vbCrLf & _
         "bei Verwendung von CDate(...)" & vbCrLf & _
         "*ODER* ein wirres Datum.", vbInformation

'* Hier wird ein Leufzeitfehler (13) generiert:
  '* Typen unvertraeglich
  MsgBox "Sowas kann bei CDate() daraus werden :-)" & vbCrLf & _
         CDate( CStr(iTag) & "." & CStr(iMonat) & "." & CStr(iJahr) ), _
                vbQuestion, _
         CStr(iTag) & "." & CStr(iMonat) & "." & CStr(iJahr)
End Sub
' -->
</SCRIPT>

<SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript1.1">
<!--
function DatumAddierenJS(iTag, iMonat, iJahr) {

var newDateObj = new Date(iJahr, iMonat-1, iTag);
  alert(iTag + "." + iMonat + "." + iJahr + "\n" + newDateObj.toString());
  return true;
}
//-->
</SCRIPT>
</head>
<body>

<FORM ID="frmDatum">
<P>
Die <B>'33.2.1999'</B>-Buttons zeigen den <B>5. März</B>.
Beim VBS-Beispiel wird zusätzlich ein Laufzeitfehler ausgelöst,
wenn anstelle DateSerial() z.B. CDate() verwendet wird. Beides wird demonstriert
<BR>
<B>'Monatsende'</B> liefert eben dieses: aus dem 0.3.1999 wird der 28.2.1999.
Bei JS wird das GMT bzw. UTC-Format angezeigt.
</P>
<P>
VBScript:  
<INPUT TYPE="button" VALUE="33.2.1999"
  LANGUAGE="VBScript"
  onclick="DatumAddierenVBS 33,2,1999">
 
<INPUT TYPE="button" VALUE="Monatsende"
  LANGUAGE="VBScript"
  onclick="DatumAddierenVBS 0,3,1999">
</P>
<P>
JavaScript:
<INPUT TYPE="button" VALUE="33.2.1999"
  LANGUAGE="JavaScript1.1"
  onclick="DatumAddierenJS(33,2,1999)">
 
<INPUT TYPE="button" VALUE="Monatsende"
  LANGUAGE="JavaScript1.1"
  onclick="DatumAddierenJS(0,3,1999)">
</P>
</FORM>

</body>
</html>