Webservices sind ja eine tolle Sache. Alles ist genau spezifiziert, das ganze funktioniert plattformübergreifend auf Basis von XML. Soweit zumindest die graue Theorie.
Wahr ist vielmehr ...
Datumswerte werden im Rahmen von Web Services, so die Simple Object Access Protocol (SOAP) 1.1 Spezifikation (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383514") gemäß der W3C Spezifikation XML Schema Part 2: Datatypes (http://www.w3.org/TR/xmlschema-2/#date") definiert. Man beachte, dass an beiden Spezifikationen IBM-Mitarbeiter beteiligt waren. Ein Übergabewert vom Typ Datum (xsd:date) hat daher das Format "YYYY-MM-DD". Also vier Ziffern für das Jahr, ein Bindestrich (Minus), dann zwei Ziffern für den Monat (01-12), wieder ein Bindestrich (Minus) und dann nochmals zwei Ziffern für den Tag (01-31). Nicht sonderlich schwierig, wenn man den übergebenen Wert auseinanderzwirbeln will -- möchte man meinen.
Wechseln wir mal von der grauen Theorie zu Praxis in der Form von Web Services unter IBMs Lotus Domino 7 Server. Dieser kann ganz wunderbar Web Services anbieten. Ich hab mal ein kleines, primitives geschrieben, um das Problem zu zeigen:
%INCLUDE "lsxsd.lss"
Class i18n
Sub NEW
End Sub
' Call this webservice twice! Once with a a day > 12 and once with a day <= 12
' Notice the difference? ;)
Function GetMonthFromDate(parameter As XSD_DATE) As String
Dim datetime As NotesDateTime
Set datetime = parameter.GetValueAsNotesDateTime()
Print "Date: " & Cstr(datetime.DateOnly)
Print "Month: " & Cstr(Month(datetime.DateOnly))
GetMonthFromDate = "Month: " & Cstr(Month(datetime.DateOnly))
End Function
End Class
Schnuckelig, oder? Macht im Prinzip nichts anderes, als aus dem Übergebenen Datum den Monat auszulesen. IBM war sogar so nett/klug/vorausschauend, den XSD_DATE Wert als NotesDateTime Wert zurückzuliefern, damit man korrekt mit den Datumswerten arbeiten kann (ich sehe Bernhard gerade vor Freude auf- und ab hüpfen).
Um so größer war dann mein Erstaunen, als ich dieses Webservice dann mit ein paar Werten aufrief.
Ruft man dieses nämlich mit dem (angeblichen) Todestag von Elvis (2007-08-16) auf, so ergibt sich folgende (erwartete) Ausgabe auf dem Server:
16.08.2007 15:47:25 HTTP Server: Agent printing: Date: 16.08.2007
16.08.2007 15:47:25 HTTP Server: Agent printing: Month: 8
Nimmt man allerdings ein einen Tag <= 12, z.B. den Geburtstag von Ian Anderson (2007-08-10), so sieht das etwas seltsamer aus:
16.08.2007 15:49:47 HTTP Server: Agent printing: Date: 08.10.2007
16.08.2007 15:49:47 HTTP Server: Agent printing: Month: 10
Hallo? Da muss man schon sehr bewusst schlecht und falsch programmieren, wenn man diese Konvertierung verhaut, oder?
Und bevor jemand fragt - der INI-Parameter DateOrder (http://www.ibm.com/developerworks/lotus/library/ls-timelyinfo/") hat KEINEN Einfluss auf die Konvertierung im Web Service.
Anbei noch die Demo-DB, ich geh jetzt mal einen ESR bei der IBM aufmachen. Testen lässt sich das ganze recht bequem mit http://www.soapui.org/ , das dazugehörige WSDL gibts unter http://server/pfad/ws_i18n.nsf/i18n?WSDL
Solche Bugs passieren mir täglich, wenn ich unter Zeitdruck Projekte durchführe (wenn ich in der Umgebung keine Unit-Tests einsetzen kann).
Der Bug ist interessant, weil es so aussieht als hätte da jemand was getürkt.
if (month > 12) {
date = month;
month = date;
}
Viel schlimmer find ich, dass das nicht viel früher aufgefallen und gefixt worden ist.
Zeigt aber auch, dass das Design-Element Webservices in Domino nicht so oft eingesetzt wird.
Im Grunde ist die ganze Webservice Story in Domino sowieso hoffnungslos. Intern basiert das auf dem java jakarta Projekt Axis1. Inzwischen gibts aber das völlig neu (zum größten Teil von 2 Entwicklern aus Sri Lanka, btw.) als Axis2. Es gibt interessante benchmarks in denen Axis2 wg. moderneren XML Parsern mehrfach (12 bis 40x) schneller abgeschnitten hat.
Gruß Axel