Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]funkcja obliczajaca wiek
Forum PHP.pl > Forum > Przedszkole
pela222
Cześć,

mam taki plik:
  1. class Person
  2. {
  3. /**
  4.   * @var bool
  5.   */
  6. private $dob = '';
  7. private $age = '';
  8.  
  9. /**
  10.   * @param string $dob
  11.   */
  12. public function setDob($dob)
  13. {
  14. $this->dob = $dob;
  15. }
  16.  
  17. /**
  18.   * @return string
  19.   */
  20. public function getDob()
  21. {
  22. return $this->dob;
  23. }
  24. }


Chialem zbudować funkcje dla potrzeb oblczenia wieku osoby na podstawie daty urodznia. Kiedyś używałem czegoś na kształt poniżej ale nie potrafie tego użyć w strukturze funkcji / klas.

  1. public function setAge($age ){
  2. $now = new DateTime(); //dzisiejsza data
  3. //echo $now->format('Y-m-d');
  4. $date = new DateTime($dob); //format daty dla potrzeb obliczenia wieku osoby na podstawie dob
  5. //echo $dob1->format('Y-m-d');
  6. $this->age = $now->diff($date); //oblicz wiek...odwołąnie do wieku w formacie echo '.$age->y.'
  7. }
  8.  
  9.  
  10. public function getAge(){
  11. return $this->age;
  12. }


Dziekuje z góry za pomoc jak to zrobić.
Crozin
1. W komentarzu podajesz, że Person::$dob jest typu bool po czym przypisujesz domyślnie pustego stringa? PHP na takie coś pozwala, ale wyzbądź się takich paskudnych praktyk.
2. Metoda nazywa się setAge() więc raczej powinna przyjąć wiek jako liczbę, a nie datę urodzenia (setDateOfBirth()).
3. Przecież na dobrą sprawę ten kod jest po prostu do przekopiowania w klasę (pomijając dwa powyższe punkty).
bobek358
Po pierwsze zobacz co zwróci $now->diff($date); - będzie to tablica w której różnica ilości dni będzie w kluczu: days.

  1. $interval = $datetime1->diff($datetime2);
  2. echo $interval->format('%R%a days');


i tutaj błąd:

  1. $date = new DateTime($this -> dob);
nospor
Cytat
Po pierwsze zobacz co zwróci $now->diff($date); - będzie to tablica w której różnica ilości dni będzie w kluczu: days.
@bobek.... przeciez autor w komentarzu wyraźnie napisal jak sie dobrac do tego diff.... czytamy czytamy i jeszcze raz czytamy, potem sie wymądrzamy wink.gif
aniolekx
dodam swoje 3 grosze ;p

data urodzenia powinna byc przekarzana w kontruktorze, a setter dla niej usuniety. W kontruktorze powinno by takze wywolanie dla metody liczacej wiek.
bobek358
Cytat(nospor @ 4.08.2015, 11:44:36 ) *
@bobek.... przeciez autor w komentarzu wyraźnie napisal jak sie dobrac do tego diff.... czytamy czytamy i jeszcze raz czytamy, potem sie wymądrzamy wink.gif


Racja, nie doczytałem facepalmxd.gif
pela222
Hej,
dziękuje ze szybką odpowiedz. Niestety z tego co widzę to wszyscy trzej już wiecie jakie jest rozwiązanie a ja dalej nic nie rozumiem. Doceniam uwagi typu:
Cytat
data urodzenia powinna byc przekarzana w kontruktorze, a setter dla niej usuniety

,ale ponieważ siadam do php bardzoooo sporadycznie to niestety nic mi to nie mówi. sad.gif
Podpowiedz
Cytat
3. Przecież na dobrą sprawę ten kod jest po prostu do przekopiowania w klasę
jest bardzo czytelna ale oczywiście że:
  1. class Person
  2. {
  3. private $now = new DateTime(); //dzisiejsza data //echo $now->format('Y-m-d');
  4. private $date = new DateTime($dob);
  5. }
jest nieprawidłowe...wiec i ta oczywista oczywistość dla was nie jest oczywista dla Przedszkolaka.
Oczywiście mógłybym zacząć czytać manual php i po 5-8 godzinach dojść za pomocą waszych uwag do rozwiązania i przy okazji nauczyć się wielu innych rzeczy związanych z php.
Czy jest szansa na poprawny kod z komentarzem co sie gdzie dzieje.
Dziękuje za waszą pomoc i zrozumienie.
ctom
a nie łatwiej skorzystać z czegoś co już istnieje ? np. biblioteki Carbon

potem tylko :

  1. $person = \Carbon\Carbon::createFromDate(1999,2,30);
  2. $now = \Carbon\Carbon::now();
  3.  
  4. $val = $now->diffInYears($person);

pela222
Cytat(ctom @ 4.08.2015, 12:04:55 ) *
a nie łatwiej skorzystać z czegoś co już istnieje ? np. biblioteki Carbon

potem tylko :

  1. $person = \Carbon\Carbon::createFromDate(1999,2,30);
  2. $now = \Carbon\Carbon::now();
  3.  
  4. $val = $now->diffInYears($person);


Wolałbym uniknąć strzelania z armaty do wróbla. Potrzebuje zrobić to dla dwóch zmiennych.
Jeżeli jest chętny na wskazanie mi rozwiązania bedę wdzięczny.
Pozdrawiam.
bobek358
Taki szybki kod:

  1. <?php
  2.  
  3. $object = new Person('1987-01-01');
  4. echo $object->getAge();
  5.  
  6. class Person
  7. {
  8.  
  9. private $dob = '';
  10. private $age = 0;
  11.  
  12. public function __construct($dob)
  13. {
  14. $this->dob = $dob;
  15. $this->setAge();
  16. }
  17.  
  18. public function getDob()
  19. {
  20. return $this->dob;
  21. }
  22.  
  23. public function getAge()
  24. {
  25. return $this->age;
  26. }
  27.  
  28. public function setAge()
  29. {
  30. $now = new DateTime();
  31. $date = new DateTime($this->dob);
  32. $interval = $now->diff($date);
  33. $this->age = $interval->y;
  34. }
  35.  
  36. }
pela222
Dziękuje wszystkim za uwagi. Ostateczne rozwiązanie wyglada tak:
  1. class Person
  2. {
  3. private $dob = '';
  4. private $age = '';
  5.  
  6.  
  7. /**
  8.   * @param $dob
  9.   */
  10. public function setDob($dob)
  11. {
  12. $this->dob = $dob;
  13. $this->setAge(); //to dodałem aby obliczyć wiek
  14. }
  15. /**
  16.   * @return
  17.   */
  18. public function getDob()
  19. {
  20. return $this->dob;
  21. }
  22.  
  23. /**
  24.   * @param string $age
  25.   */
  26. public function setAge(){
  27. $now = new DateTime(); //dzisiejsza data
  28. //echo $now->format('Y-m-d');
  29. $date = new DateTime($this->dob); //format daty dla potrzeb obliczenia wieku osoby na podstawie dob
  30. //echo $dob1->format('Y-m-d');
  31. $interval = $now->diff($date);
  32. //EDIT nr2
  33. $this->years = $interval->y; //oblicz wiek...odwołąnie do wieku w formacie echo '.$age->y.'
  34. $this->months = $interval->m;
  35. $this->days = $interval->d;
  36. $this->age = $this->years .' Year(s)';
  37. //kiedy miesiace a kiedy lata
  38. if($this->years === 0) {
  39. $this->age = $this->months .' Month(s)';
  40. if($this->months === 0) {
  41. $this->age = $this->days .' Day(s)';
  42. }
  43. }
  44. }
  45. /**
  46.   * @return string
  47.   */
  48. public function getAge(){
  49. //EDIT nr1
  50. if (($this->age > 21 && ($this->age % 10 == "2" || $this->age % 10 == "3" || $this->age % 10 == "4")) || $this->age < 5) {
  51. $koncowka = "lata";
  52. } else {
  53. $koncowka = "lat";
  54. }
  55. return $this->age . ' ' . $koncowka;
  56. }
  57. }


Możliwe że bede chciał znaleść udoskonalenie tego obliczania.
1) Dla osoby gdzie wiek jest <0 żeby policzyć miesiące
2) wpisanie lat / lata np. 31 lat, 32 lata etc (gdzieś takie coś widziałem wiec może jutro poszukam i zobacze czy ogarniam temat smile.gif

===EDIT nr1====
Punkt nr 2 już znalazłem i dodałem smile.gif Happy hours smile.gif

===EDIT nr2===
Zrobiłęm punkt nr1 czyli obliczanie miesiecy dla osoby o mniej niz 1 rok życia. I jest ok.

PYTANIE
Ale mam jeden problem. Jeśli mam osobę bez daty urodzenia to mi oblicza że ma 2015 lat. Gdzie jest problem.
Jak zwykle dziękuje za podpowiedzi.
Pozdrawiam.
nospor
Cytat
Ale mam jeden problem. Jeśli mam osobę bez daty urodzenia to mi oblicza że ma 2015 lat. Gdzie jest problem.
Jak to mówią: między krzeslem a monitorem wink.gif
Tak ciezko sie domyslic, ze gdy nie ma daty urodzenia, to nie wykonywac zadnych obliczen? No wiesz, masz uzyc IF.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.