Zugegeben, ein Projekt über das ich im Blog noch nie gesprochen habe ist coffeestats.org. Holger wollte sich mit PHP beschäftigen, ich mit Google Charts. Wir taten uns zusammen. Das ist nun über ein Jahr her. Es geht grundsätzlich nur darum den eigenen Koffeein-Konsum zu tracken und statistisch auszuwerten. Auf der Site haben im Grunde nur Holger, ein paar Kollegen und ich rumgelurked.
Vor kurzem empfand Jan es für sinnvoll einen kleinen Blogpost über das Projekt zu schreiben. In planet.debian.org. Klar die Hits würden ein bisschen hochgehen. Aber so wirklich an Registrierungen hab ich nicht geglaubt.
Tatsächlich haben sich aber wirklich Menschen angemeldet. 40 Stück in am ersten Tag. Von London, Montreal, Zürich, Schweden über Griechenland zu Madrid. Alles dabei. Fand ich witzig. Bis ich mir die “Overall Statistics” ansah. Wer zur Hölle säuft um 3 Uhr nachts Kaffee… und bucht das auch noch auf coffeestats.org? Erstmal etwas rumdebuggt.
INSERT INTO cs_coffees VALUES ('', '$userid' , NOW() );
Tjo. Problem gefunden. Wann immer jemand (egal wo) auf “Ich hab gerade ne leckere Tasse Kaffee vor mir stehen” drückte, hab ich diese unter der aktuell vorherrschenden ServerTime abgespeichert. Für Holger und mich hätte das ja super funktioniert. Wir hätten damals nicht gedacht das sich dort überhaupt jemand anmeldet. Schon garnicht jemand der nicht in unserer Zeitzone wohnt (und kein Bot ist).
Time zone settings are normally not the first thing you think of when working on a web project with PHP
Was tun? Auch wenn ich mir sicher bin dass die registrierten User da nicht auf Dauer aktiv sein werden, hatt mich das trotzdem genervt. Was ist wenn ich mal in den Urlaub fahre und Kaffee trinke … mit einem falschen Timestamp? Schrecklich!
Nach etwas herumgoogeln stellte sich heraus, dass man die Client Zeit wohl mit JavaScript feststellen möchte. Und das Date Formatting mit JS unglaublich hässlich ist.
function coffeetime(d){
function pad(n){return n<10 ? '0'+n : n}
return d.getFullYear()+'-'
+ pad(d.getMonth()+1)+'-'
+ pad(d.getDate())+' '
+ pad(d.getHours())+':'
+ pad(d.getMinutes())+':'
+ pad(d.getSeconds())}
var d = new Date();
function AddPostData() {
document.getElementById('coffeetime').value = coffeetime(d);
document.getElementById('form').submit();
}
Resultiert in dem tollen Stamp 2013-02-15 12:47:41
den ich an die gewünschte HTML Form bastle.
Mit viel Handliebe Nullen padden müssen, 6 Funktionen callen und getMonth Index Workaround. Pfui.
Dann noch durch den XSS und SQL Injection Validator schicken und fertig. Jetzt sind die User im Zweifel selbst für falsche Timestamps verantwortlich und ich kann beruhigt $irgendwohin in Urlaub fahren.
Sollte ich nochmal vor so eine Aufgabe gestellt werden würde ich die Timestamps aber in Unix-Epoch in UTC Zeitzone abspeichern und dann nur noch die Zeitzonen zum herumrechnen benutzen. Die Variante gefällt mir (gestern von Mullet erklärt bekommen) aber der Zug is jetzt definitiv schon abgefahren. Ums mit seinen Worten zu sagen “Fehler, die man nur einmal macht.” :)
Comments (17)