Avatar billede dennism Nybegynder
08. juni 2003 - 23:32 Der er 54 kommentarer og
2 løsninger

mySQL/PHP - opbevaring af fødselsdags dato

Jeg skal have en række i en af mine tabllen, som angiver hvornår en person er født.
Mit spørgsmål er nu, hvilken format der er bedst til dette formål.

Jeg skal bruge fødselsdagsdatoen, vil at angive personens alder, og jeg skal have mulighed for at mange en system hvor man kan søge i databasen, og finde personer med en valgt alder.

Hvilket formal foreslår i at jeg bruger, og hvad er smartest?
Avatar billede ahv Nybegynder
08. juni 2003 - 23:52 #1
Jeg ville gøre bruge af et date felt eller hvis fødslesdagen skal være helt præcis så datetime.
Avatar billede noaz Nybegynder
08. juni 2003 - 23:52 #2
format.. jeg ville nok bruge date(Y-m-d) fx: 2003-08-06
Avatar billede tipsen Nybegynder
08. juni 2003 - 23:59 #3
Se forøvrigt bruger-kommentarerne på http://www.mysql.com/doc/en/Date_and_time_functions.html samt mit relaterede spørgsmål på http://www.eksperten.dk/spm/361292.
Avatar billede ahv Nybegynder
09. juni 2003 - 00:19 #4
Ud fra fødselsdatoen i databasen, kan du så udregne alderen med:

function alder ($aar,$maaned,$dag) {
    $tid = (time()) - mktime(0,0,0,$maaned,$dag,$aar);
    $antalaar = intval($tid / 31532400);
    return $antalaar;
}

$query = mysql_query("SELECT YEAR(felt) as year, MONTH(felt) as month, DAYOFMONTH(felt) as day FROM tabel WHERE kolonne='noget'");
while ($row = mysql_fetch_array($query)) {
    echo alder ($row['year'],$row['month'],$row['day']). " år gammel<br>";
}
?>
Avatar billede tipsen Nybegynder
09. juni 2003 - 00:21 #5
Eller bare gøre det med følgende forespørgsel:

SELECT firstname, lastname,
DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(birthdate, '%Y') -
(DATE_FORMAT(CURDATE(), CONCAT(YEAR(CURDATE()),'-%m-%d')) < DATE_FORMAT(birthdate, CONCAT(YEAR(CURDATE()), '-%m-%d'))) + 1 AS bdayage FROM table
Avatar billede tipsen Nybegynder
09. juni 2003 - 00:22 #6
< skal være <= !!

SELECT firstname, lastname,
DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(birthdate, '%Y') -
(DATE_FORMAT(CURDATE(), CONCAT(YEAR(CURDATE()),'-%m-%d')) <= DATE_FORMAT(birthdate, CONCAT(YEAR(CURDATE()), '-%m-%d'))) + 1 AS bdayage FROM table
Avatar billede dennism Nybegynder
09. juni 2003 - 14:02 #7
Undskyld.. Jeg er ikke helt med!
For at lave det smarteste system, hvordan skal datoen da engives i min database?
Skal man have et kolonne til både dag, måned og år, eller skal man blot bruge et felt, hvor datoen bliver angivet? Dette kunne f.eks. gøres med time()!?

For så vil det jo være meget nemt f.eks. at finde de rækker i tabellen, hvor alder f.eks. er under 10. Så siger man jo bare noget i retningen af: WHERE birtyday < time()-10år
Avatar billede tipsen Nybegynder
09. juni 2003 - 14:08 #8
Som skrevet ovenfor gemmes datoen i et date-felt.
Avatar billede dennism Nybegynder
09. juni 2003 - 14:22 #9
Ja, men med hvilken funktion skal jeg udfylde dette date-felt?
Avatar billede ahv Nybegynder
09. juni 2003 - 14:33 #10
Du sætter datoen med: $dato = date("Y-m-d");
Når du indsætter: INSERT INTO tabel (dato) VALUES ('$dato')
Avatar billede dennism Nybegynder
09. juni 2003 - 14:40 #11
Hvad hvis en bruger skriver at hans fødselsdag er:
Dag:23
Måned:01
År:1987

Hvordan skal jeg så omskrive dette til date-værdi?
Avatar billede tipsen Nybegynder
09. juni 2003 - 14:59 #12
$year = 1987;
$month = 1;
$day = 23;
$nydato = "$year-$month-$day";
Avatar billede dennism Nybegynder
09. juni 2003 - 15:05 #13
Tipsen >>

Det er jeg med på, men skal dato-formatet bare stå sådan, for at de funktioner i lavede kan bruges?
Avatar billede tipsen Nybegynder
09. juni 2003 - 15:08 #14
ja.

Læs evt http://www.mysql.com/doc/en/DATETIME.html for uddybning.
Avatar billede ahv Nybegynder
09. juni 2003 - 15:11 #15
Ja, der skal ikke andet til :o)
Avatar billede ahv Nybegynder
09. juni 2003 - 15:12 #16
Min function har sikkert problemer med folk der er født før 1970, lav den om til:

function alder ($aar,$maaned,$dag){
    if($aar<1970){$rig=$aar;$aar=1970;$foer=1;}
    $tid=(time())-mktime(0,0,0,$maaned,$dag,$aar);
    $antalaar=intval($tid/31532400);
    if(isset($foer)){$antalaar+=1970-$rig;} return $antalaar;
}
Avatar billede dennism Nybegynder
09. juni 2003 - 15:19 #17
Hvordan kan jeg så spitte de 1987-01-23 op til $year = 1987, $month = 01, $day = 23 igen (når folk skal redigere deres fødselsdag)?

tipsen >>

Du skrev:
$month = 1;

Skal det ikke være "01"?
Avatar billede ahv Nybegynder
09. juni 2003 - 15:27 #18
Redigere deres fødselsdag? Den ændre sig vist ikke gennem livet ? ;o)
Avatar billede dennism Nybegynder
09. juni 2003 - 15:29 #19
ahv >>

Nej, normalt gør den ikke! Men jeg er alligevel nød til at give brugeren mulighed for at ændre sin fødselsdag (f.eks. hvis en anden person overtager brugeren)..
Avatar billede ahv Nybegynder
09. juni 2003 - 15:29 #20
Men hvis du mener at de har indtastet forkert, og skal rette den så kan du bruge mit eksempel:

$query = mysql_query("SELECT YEAR(felt) as year, MONTH(felt) as month, DAYOFMONTH(felt) as day FROM tabel WHERE kolonne='noget'");
$row = mysql_fetch_array($query);
$year = $row['year'];
$month = $row['month'];
$day = $row['day'];

Så har du året i variablen $year osv.
Avatar billede dennism Nybegynder
09. juni 2003 - 15:34 #21
I skal nok få flere point, end der er på bordet nu. Men jeg kan lige så godt få løst alle mine problemer ang. dette emne på samme tid.

Hvis vi nu antager at en bruger vælger at han/hun vil søge i brugere som har en alder fra 15-16, hvordan kan jeg så gøre det udfra det tal jeg har i kolonnen (f.eks 1987-01-23)?
Avatar billede ahv Nybegynder
09. juni 2003 - 15:45 #22
Hvis vi tager i dag og vil have alle mellem 15-16, så må deres tidligeste fødselsdag være:

året - 16 = 1987
måneden = 06
dagen - 1 = 08
1987-06-08

deres seneste fødselsdag må være:

året - 15 = 1988
måneden = 06
dagen = 09
1988-06-09

Så 15-16 årige må have fødselsdag mellem: 1988-06-09 & 1987-06-08
Håber jeg da på ;o) Ellers må jeg have lavet en fejl.
Avatar billede dennism Nybegynder
09. juni 2003 - 15:47 #23
Oki ahv, den mulighed havde jeg ikke lige tænkt på!
Men hvordan laver jeg "1987-06-09" på den nemmeste måde?
Avatar billede dennism Nybegynder
09. juni 2003 - 15:49 #24
tipsen >>

Må jeg lige bede om et svar fra din side?
Avatar billede ahv Nybegynder
09. juni 2003 - 16:02 #25
Hvis du nu har to felter, en minimums alder og en maximum alder, så kan du beregne dig frem til den største og leveste dato (eksempel med 15-16)

<?php
$datemaxyear = date("Y", (time()-(60*60*24*365*16)));
$datemaxmonth = date("m");
$datemaxday = date("d", (time()-(60*60*24)));
$maxdate = $datemaxyear ."-". $datemaxmonth ."-". $datemaxday;

$dateminyear = date("Y", (time()-(60*60*24*365*15)));
$dateminmonth = date("m");
$dateminday = date("d");
$mindate = $dateminyear ."-". $dateminmonth ."-". $dateminday;

echo "Fødselsdagen for en 15-16 årig er mellem: ". $maxdate ." & ". $mindate;
?>
Avatar billede tipsen Nybegynder
09. juni 2003 - 16:04 #26
SELECT firstname, lastname,
DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(birthdate, '%Y') -
(DATE_FORMAT(CURDATE(), CONCAT(YEAR(CURDATE()),'-%m-%d')) < DATE_FORMAT(birthdate, CONCAT(YEAR(CURDATE()), '-%m-%d'))) + 1 AS bdayage FROM table WHERE bdayage BETWEEN 15 AND 16
Avatar billede tipsen Nybegynder
09. juni 2003 - 16:06 #27
For at vælge personer mellem 15 og 16 år - begge inkl. dvs. i praksis fra 15 år til 17år-1dag
Avatar billede tipsen Nybegynder
09. juni 2003 - 16:09 #28
ups - og det skulle selvfølgelig stadig være <=m dvs:

SELECT firstname, lastname,
DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(birthdate, '%Y') -
(DATE_FORMAT(CURDATE(), CONCAT(YEAR(CURDATE()),'-%m-%d')) <= DATE_FORMAT(birthdate, CONCAT(YEAR(CURDATE()), '-%m-%d'))) + 1 AS bdayage FROM table WHERE bdayage BETWEEN 15 AND 16
Avatar billede ahv Nybegynder
09. juni 2003 - 16:10 #29
Så havde jeg klokket i det ;o)

<?php
$datemaxyear = date("Y", (time()-(60*60*24*365*17)));
$datemaxmonth = date("m");
$datemaxday = date("d", (time()-(60*60*24)));
$maxdate = $datemaxyear ."-". $datemaxmonth ."-". $datemaxday;

$dateminyear = date("Y", (time()-(60*60*24*365*15)));
$dateminmonth = date("m");
$dateminday = date("d");
$mindate = $dateminyear ."-". $dateminmonth ."-". $dateminday;

echo "Fødselsdagen for en 15-16 årig er mellem: ". $maxdate ." & ". $mindate;
?>

Som Tommy ganske rigtigt siger så er det jo til 17 år - 1 dag.
Avatar billede tipsen Nybegynder
09. juni 2003 - 16:14 #30
ahv: Du glemmer at tage højde for skudår...
Avatar billede ahv Nybegynder
09. juni 2003 - 16:15 #31
Til højre med skudår ;o)
Avatar billede tipsen Nybegynder
09. juni 2003 - 16:20 #32
Det minder mig om det der spørgsmål straszek havde for nogle uger siden med "kalenderen der fungerede perfekt - bortset fra i juni"... ;-)
Avatar billede ahv Nybegynder
09. juni 2003 - 16:24 #33
De kalendere er som regel nogen af dem der virkelige koster. ;o)
Avatar billede dennism Nybegynder
09. juni 2003 - 17:02 #34
tipsen >>

Tager din metode højre for skudår?
Avatar billede tipsen Nybegynder
09. juni 2003 - 17:19 #35
Da jeg kun benytter de indbyggede funktioner i MySQL regner jeg stærkt med at der bliver taget højde for skudår - ellers ville jeg da være pænt skuffet over de folk der sidder og koder MySQL :-)

Så vidt jeg kan gennemskue er der ikke nogle huller/bugs i den sql-forespørgsel jeg har læsset af...
Avatar billede dennism Nybegynder
09. juni 2003 - 17:24 #36
Har du lyst til at forklare mig hvad det er de forskellige funktioner i koden gør?
Avatar billede dennism Nybegynder
09. juni 2003 - 17:32 #37
Har også lige et sidste spørgsmål mere.. Hvordan tjeker jeg om den indtastede fødselsdag er korrekt?
Avatar billede dennism Nybegynder
09. juni 2003 - 17:37 #38
Og.. Er det korrekt at kolonnel til "birthtime" er af typen "date"?
Avatar billede dennism Nybegynder
09. juni 2003 - 17:37 #39
kolonnen even
Avatar billede tipsen Nybegynder
09. juni 2003 - 17:47 #40
Rettelse - efter jeg begyndte argumentationen kunne jeg se der var problemer - fandt frem til følgende forenkling og forstår egentlig ikke det fungerede tidligere... (har samme sql-sætning kørende herhjemme og selv på dagen passede det!)

Rigtig udgave:

DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(birthdate, '%Y') -
(DATE_FORMAT(CURDATE(), '%m-%d') > DATE_FORMAT(birthdate, '%m-%d')) AS age,


DATE_FORMAT(NOW(), '%Y') // Giver aktuelt årstal - 2003
- DATE_FORMAT(birthdate, '%Y') //Subtraherer fødselsårstal - eks. 1985

Dette alene fungerer fint, hvis man HAR haft fødselsdag i indeværende år - i eksemplet ovenfor er personen 18 år, men kun, hvis personen har haft fødselsdag i 2003 - derfor skal der trækkes 1 år fra, hvis vedkommende ikke har haft fødselsdag endnu i indeværende år, hvilket nedenstående sørger for!

- (DATE_FORMAT(CURDATE(), '%m-%d') > DATE_FORMAT(birthdate, '%m-%d'))

Bemærk at det resultatet (0 eller 1) af den logiske test > der fratrækkes - hvis venstresiden (dags dato) er større end højresiden (fødselsdag), betyder det at personen har haft fødselsdag og der skal ikke fratrækkes noget - da udtrykket så er sandt returnerer det 0 og der trækkes ikke noget fra! Hvis udtrykket er falsk, dvs. højresiden er størst og personen endnu ikke har haft fødselsdag fratrækkes 1 (som svarer til falsk) og vi får alt i alt personens korrekte alder!

Det hele hænger altså på den lille korrektion der ser på om personen har haft fødselsdag eller ej i indeværende år - og den udnytter at mysql returnerer 0 eller 1 afhængig af om et udtryk er sandt eller falsk.

Meget rart lige at kommentere svaret, så jeg kunne finde mine fejl :-)
Avatar billede tipsen Nybegynder
09. juni 2003 - 17:49 #41
birthdate skal lagres i date felt ja - som skrevet et par gange i kommentarer tidligere!

Hvis du vil undersøge om fødselsdagen er korrekt... - spørg personens mor :-)
Avatar billede dennism Nybegynder
09. juni 2003 - 18:03 #42
tipsen >>

Jeg mindes da at have set en funktion som kan tjekke om en dato er korrekt!?

Jeg er lidt forviret hvad angår den sql-kode nu.. Kan du ikke lige smide den færdige kode, sådan jeg er sikker på at det virker som det skal!
Avatar billede tipsen Nybegynder
09. juni 2003 - 18:52 #43
DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(birthdate, '%Y') -
(DATE_FORMAT(CURDATE(), '%m-%d') > DATE_FORMAT(birthdate, '%m-%d')) AS age

Til at checke gyldigheden af en dato kan du bruge checkdate() - Se: http://dk.php.net/manual/en/function.checkdate.php
Avatar billede dennism Nybegynder
09. juni 2003 - 18:55 #44
Tusind tak for hjælpen...
Avatar billede dennism Nybegynder
12. juni 2003 - 20:04 #45
ahv >>

Jeg kører nu den funktion du lavede:

function age ($aar,$maaned,$dag) {
    if($aar<1970){$rig=$aar;$aar=1970;$foer=1;}
    $tid=(time())-mktime(0,0,0,$maaned,$dag,$aar);
    $antalaar=intval($tid/31532400);
    if(isset($foer)){$antalaar+=1970-$rig;} return $antalaar;
}

Men den returnerer:

Warning: mktime() [function.mktime]: Windows does not support negative values for this function in user.php on line 4
;

Virker den ikke i windows, eller hvad?

Kan jeg bruge denne funktion istedet:

function age($day, $month, $year) {
  $nowD = date("j");
  $nowM = date("n");
  $nowY = date("Y");
  //hvis vi har passeret personens fødselsdag i indeværende år:
  if($month < $nowM || $month == $nowM && $day <= $nowD) {
    return (int) ($nowY - $year);
  }
  //hvis vi endnu ikke har passeret personens fødselsdag i indeværende år:
  else {
    return (int) ($nowY - $year - 1);
  }
}
Avatar billede dennism Nybegynder
10. juli 2003 - 11:56 #46
tipsen >>

Jeg har problemer med den funktion du lavede i "09/06-2003 16:09:18".
Mine fødselsdagsdato ligger nu i: birthdate_day, birthdate_month og birthdate_year.

Din funktion er laver til at det ligger i samme felt! Hvordan får jeg funktionen til at virke?

Du skal nok få 80 point ekstra, for at svare!
Avatar billede tipsen Nybegynder
10. juli 2003 - 12:09 #47
Du ligger informationen i et felt :-) (Ellers har jeg ikke noget bud uden det bliver voldsomt kompliceret!)
Avatar billede dennism Nybegynder
10. juli 2003 - 12:15 #48
Hvordan kan jeg ligge informationerne i et felt under en "mysql query"?
Avatar billede tipsen Nybegynder
10. juli 2003 - 12:21 #49
Ikke forstået.
Avatar billede dennism Nybegynder
10. juli 2003 - 12:34 #50
Lige nu har jeg denne kode:

$mysql = mysql_query("SELECT username, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(birthdate, '%Y') -
(DATE_FORMAT(CURDATE(), CONCAT(YEAR(CURDATE()),'-%m-%d')) <= DATE_FORMAT(birthdate, CONCAT(YEAR(CURDATE()), '-%m-%d'))) + 1 AS bdayage FROM users WHERE $search ORDER BY username ASC");

Hvad skal jeg indsætte i denne, for at få værdien af birthdate_day, birthdate_month og birthdate_year over i birthdate.. Kan jeg gøre noget ala: "birthdate_year-birthdate_month-birthdate_day" AS birthdate ?
Avatar billede tipsen Nybegynder
10. juli 2003 - 12:55 #51
Det kan du sandsynligvis vha. CONCAT(), men det ville være meget nemmere bare at kombinere de 3 felter til et felt - altså ændre i selve tabellen!
Avatar billede dennism Nybegynder
10. juli 2003 - 12:56 #52
Så skal jeg altså både have birthdate_day, birthdate_month og birthdate_year og birthdate i min tabel?
Avatar billede dennism Nybegynder
10. juli 2003 - 12:57 #53
Men du ved ikke hvordan jeg kan gøre det vha, CONCAT? Synes det virker mærkeligt at skulle lave et nyt felt, for kun at bruge den til dette formål!
Avatar billede tipsen Nybegynder
10. juli 2003 - 13:10 #54
Jeg vil hellere formulere det sådan, at du samler 3 felter til 1 - det er ikke nødvendigt at have det adskilt!
Avatar billede dennism Nybegynder
10. juli 2003 - 14:42 #55
Jeg bruger denne funktion til at udregne brugerens alder, hvordan skal den så se ud, hvil det hele er i ét felt:

function age($day, $month, $year) {
  $nowD = date("j");
  $nowM = date("n");
  $nowY = date("Y");

if($month < $nowM || $month == $nowM && $day <= $nowD) {
    return (int) ($nowY - $year);
} else {
    return (int) ($nowY - $year - 1);
}

}
Avatar billede dennism Nybegynder
10. juli 2003 - 14:43 #56
Hvordan gør jeg det med CONCAT, som du snakkede om? Tror det vil være noget nemmere i mit tilfælde!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester