Geburtsdatum in Datenbank speichern über Optionsfelder

AndyAY

Grünschnabel
Hi

für mein Profil Script möchte ich gerne den Usern erlauben ihr Geburtsdatum zu speichern, damit man sehen kann wer wann Geburtstag hat.

Hab schon viele verschieden Möglichkeiten probiert, bekomms aber nicht zum laufen. Im Moment hab ich es so verfasst:

PHP:
<select name="day">
  								<option value="01">01</option>
  								<option value="02">02</option>
  								<option value="03">03</option>
  								<option value="04">04</option>
  								<option value="05">05</option>
  								<option value="06">06</option>
  								<option value="07">07</option>
  								<option value="08">08</option>
  								<option value="09">09</option>
  								<option value="10">10</option>
  								<option value="11">11</option>
  								<option value="12">12</option>
  								<option value="13">13</option>
  								<option value="14">14</option>
  								<option value="15">15</option>
  								<option value="16">16</option>
  								<option value="17">17</option>
  								<option value="18">18</option>
  								<option value="19">19</option>
  								<option value="20">20</option>
  								<option value="21">21</option>
  								<option value="22">22</option>
  								<option value="23">23</option>
  								<option value="24">24</option>
  								<option value="25">25</option>
  								<option value="26">26</option>
  								<option value="27">27</option>
  								<option value="28">28</option>
  								<option value="29">29</option>
  								<option value="30">30</option>
  								<option value="31">31</option>
								</select>
								<select name="month">
  								<option value="januar">Januar</option>
  								<option value="februar">Februar</option>
  								<option value="maerz">März</option>
  								<option value="april">April</option>
  								<option value="mai">Mai</option>
  								<option value="juni">Juni</option>
  								<option value="juli">Juli</option>
  								<option value="august">August</option>
  								<option value="september">September</option>
  								<option value="oktober">Oktober</option>
  								<option value="november">November</option>
  								<option value="dezember">Dezember</option>
								</select>
								<input name="year" type="text" value="JJJJ" size="4" maxlength="4">

Und so übergebe ich es an die Datenbank:

PHP:
	if (isset($_POST['submit']) AND $_POST['submit']=='Profil ändern'){
	
	$day = $_POST['day'];
	$month = $_POST['month'];
	$year = $_POST['year'];
	$birthday = mktime(0,0,0,$day,$month,$year);

$profile = "UPDATE 
		     profile
                 SET
		     user_bday = '". $birthday. "'
	         WHERE
		     user_id = '".$_SESSION['user_id']."'
               ";
.....

Hab auch schon statt mit mktime, mit date oder int probiert :)
Auch bin ich mir nicht ganz sicher ob die Datenbanktablle Date, Datetime oder INT tragen soll, da ich fast überall was anderes gelesen hab. Wie gesagt funktioniert hat es auf keiner weiße. :(

Danke im Voraus für Hilfe!

Mfg, Andy
 
mktime liefert einen Unix-Timestamp zurück - also die seit dem 1.1.1970 vergangen Sekunden. Prinzipiell ist es eine gute Idee, das über einen Zeitstempel zu machen (mit dem kann man einfacher rechnen als mit einem komplexen Datum wie DATE). Was ich allerdings sehe, ist das du mktime() nicht korrekt verwendest. Hier ist der Prototyp von mktime:

Code:
int mktime ([ int $hour = date("H") [, int $minute = date("i") [, int $second = date("s") [, int $month = date("n") [, int $day = date("j") [, int $year = date("Y") [, int $is_dst = -1 ]]]]]]] )

Wie du siehst, wird zu erst Monat, dann Tag und dann Jahr erwartet, du hast Monat und Tag vertauscht.

In der Datenbank würde ich tatsächlich einen INT hinterlegen. Das sieht dann zwar bei Verwendung mit phpMyAdmin etwas komisch aus - man erkennt es nicht als Datum, aber wie gesagt, es lässt sich einfacher damit rechnen.

Du kannst dann beim Abholen aus der Datenbank DATE_FORMAT (in Kombination mit FROM_UNIXTIME) verwenden oder du verwendest die PHP-Funktionen (strftime), um den Zeitstempel in ein menschen-lesbares Datum zu verwandeln.

EDIT: Was ich grad bemerkt habe: mktime() erwartet als Monat eine Zahl, keine Zeichenkette. Du müsstest also zusätzlich die $_POST['month']-Value erstmal in einen Monat als Zahl umwandeln. Das könnte man über ein Array erledigen:

PHP:
$month_names_to_digits[] = array(
  'januar' => 1,
  'februrar' => 2,
  /* usw... */
);

$month = isset($_POST['month']) ? $month_names_to_digits[$_POST['month']] : 0;

// $month evtl. noch prüfen vor dem Verwenden in mktime()...
 
Zuletzt bearbeitet:
Hi, danke für die schnelle und ausführliche Antwort!

Jedoch kommt wenn ich deinen Code verwende diese Fehlermeldung:

Parse error: syntax error, unexpected T_STRING in ....... on line 45

diese Zeile ist die die von dir: int mktime (................
 
Das ist der Prototyp ;-) Das war nicht dafür gedacht, das du das in den Code einbaust.

Ein Prototyp ist immer sozusagen die Beschreibung der Funktion. Was erwartet die Funktion für Parameter und was gibt sie zurück. Es war lediglich der Versuch, dir zu zeigen, was für Parameter (und vor allem in welcher Reihenfolge) die Funktion mktime() erwartet.
 
Hallo!

EDIT: Was ich grad bemerkt habe: mktime() erwartet als Monat eine Zahl, keine Zeichenkette. Du müsstest also zusätzlich die $_POST['month']-Value erstmal in einen Monat als Zahl umwandeln.
Anstatt die Monate umzuwandeln, würde ich sie lieber gleich als Zahl übergeben.
Das was $_POST['month'] liefert, ist ja das was Otto Normal nicht zu sehen bekommt (es sei denn er schaut in den Quelltext)..... also werden die Vaules nicht mit Monatsnamen, sondern mit Monatszahlen gefüllt..... und schon müssen die Monate nicht mehr umgewandelt werden. ;)

Und bevor ich die Formulardaten durch mktime() jagen würde, würde ich das Datum erstmal mit checkdate() auf seine Gültigkeitprüfen.
Andernfalls könnte es sonst passieren dass jemand am 31. Februar Geburtstag hat. :p

Gruss Dr Dau
 
mktime() macht da draus IMHO ein real existierendes Datum, also z.B. den 3. März bei deinem Beispiel:

PHP:
error_reporting(E_ALL|E_STRICT);
ini_set('display_errors', 1);

date_default_timezone_set('Europe/Berlin');


$t = mktime(0, 0, 0, 2, 31, 2011);
echo date("Y-m-d", $t);

Im Zweifelsfall ist das Geburtsdatum falsch ;-) Gefährlich ist das aber nicht :-) Allerdings gebe ich dir recht, Plausibilitätsprüfungen sind sinnvoll. Man kann den Timestamp ja auch wieder umwandeln um die Eingaben zu validieren.

Die Idee mit der Zahl als Value ist charmant :-)
 
mktime() macht da draus IMHO ein real existierendes Datum, also z.B. den 3. März bei deinem Beispiel:
[...]
Im Zweifelsfall ist das Geburtsdatum falsch ;-)
Das Problem ist aber dass mktime() ungefragt einfach ein anderes Datum unterstellt.
Selbst in der Annahme dass die Eingaben auf einer Übersichtsseite "Angaben überprüfen" nochmal dargestellt werden und ggf. die Möglichkeit einer Korrektur besteht, könnte das unterstellte Geburtsdatum evtl. nicht auffallen.
Ich kenne mein Geburtsdatum (wie jeder andere seins wohl auch kennt ;)), solche Angaben überfliege ich daher auf der "Angaben überprüfen"-Seite bestenfalls.
Bei der Auswahl handelt es sich ja um ein Aufklappmenü, dort könnte man auch unbemerkt mit der Maus beim selektieren verrutscht sein.
Und genau so enstehen dann Flüchtigkeitsfehler. ;)

checkdate() kann natürlich nicht prüfen ob ich am 12. oder am 27. Geburtstag habe, zumindest aber kann es das Datum auf Gültigkeit prüfen und gibt dann entweder TRUE oder FALSE zurück.
Und auf TURE/FALSE kann man entsprechend reagieren.

Ich persönlich halte die Auswahlmenüs für den Tag und den Monat sowieso für überflüssig.
Und wenn, dann würde ich auch für das Jahr ein Auswahlmenü anbieten (mit einer for-Schleife ist sowas ja schnell erledigt ;)).
Ein Textfeld mit dem voreingetragenen Value "DD.MM.YYYY" tut es auch.
Und für die ganz Blöden kann man auch ein aussagekräftiges fiktives Geburtsdatum wie z.b. "31.12.2010" nehmen..... abschreiben wird wohl noch jeder hinbekommen. ;)
Der String wird dann mittels explode() an den Punkten zerlegt und durch checkdate() gejagt.
Im Fehlerfall bekommt der User einen entsprechenden Hinweis.
Im Erfolgsfall wird der zerlegte String durch mktime() gejagt.

Gefährlich ist das aber nicht :-)
Korrekt.
Ob es sich tatsächlich um das Geburtsdatum handelt (hier im Forum bin ich ja auch erst 2005 geboren :p), prüft in den meisten Fällen sowieso niemand.
Der Aufwand und die Kosten wären einfach zu hoch (z.b. mit Postident) und lohnt sich nur dort wo es wirklich notwendig ist.
 
Und wenn du den Timestamp hast, hast du auch kein Problem mehr mit der DB. Einfach dort ein Feld vom Typ Date anlegen.

SQL:
-- Update/Insert aus einem Timestamp
UPDATE TABLE SET user_bday= FROM_UNIXTIME($phpTimestamp);

-- Zurückgeben des Date-Wert als Timestamp
SELECT UNIX_TIMESTAMP(user_bday) FROM TABLE;
 
Zuletzt bearbeitet von einem Moderator:
Hi

also ich hab mich nun entschieden das ganze Datum über ein Textfeld einzugeben :)
Nun hab ich das Problem, dass das Datum ja im englischen Format in der Datenbank ankommt, hab versucht mit:

$datum= date("d.m.Y", $_POST['user_date']);

im deutschen Format zu speichern, geht aber nicht :( hab zwar bei google viele Beschreibungen gefunden, aber die waren alle so schwer, dass ich hoffe, jemand weiß hier eine einfach Möglichkeit :)

Mfg
Andy
 
date() macht genau das umgekehrte. Es wandelt ein timestamp in ein String
Code:
string date ( string $Format [, int $Timestamp ] )

Zerlege dein Datumsstring in Tag. Monat und Jahr. Anschliessend kannst du es mittels mktime() in ein Timestamp wandeln

Nachtrag: mit strtotime() gehts auch

Test:
PHP:
$str = "5.12.2011";
$date = strtotime($str);
//Ausgabe zum überprüfen ob er die 5 als Moant oder als Tag nimmt
print_r(getdate($date));
Audgabe
Code:
Array
(
    [seconds] => 0
    [minutes] => 0
    [hours] => 0
    [mday] => 5
    [wday] => 1
    [mon] => 12
    [year] => 2011
    [yday] => 338
    [weekday] => Monday
    [month] => December
    [0] => 1323039600
)
 
Zurück