Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]funkcja obliczajaca wiek
pela222
post
Post #1





Grupa: Zarejestrowani
Postów: 85
Pomógł: 0
Dołączył: 17.04.2013

Ostrzeżenie: (0%)
-----


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ć.
Go to the top of the page
+Quote Post
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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).
Go to the top of the page
+Quote Post
bobek358
post
Post #3





Grupa: Zarejestrowani
Postów: 143
Pomógł: 22
Dołączył: 17.11.2007

Ostrzeżenie: (0%)
-----


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);
Go to the top of the page
+Quote Post
nospor
post
Post #4





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




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


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
aniolekx
post
Post #5





Grupa: Zarejestrowani
Postów: 340
Pomógł: 46
Dołączył: 31.07.2009
Skąd: A

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
bobek358
post
Post #6





Grupa: Zarejestrowani
Postów: 143
Pomógł: 22
Dołączył: 17.11.2007

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
pela222
post
Post #7





Grupa: Zarejestrowani
Postów: 85
Pomógł: 0
Dołączył: 17.04.2013

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
ctom
post
Post #8





Grupa: Zarejestrowani
Postów: 321
Pomógł: 55
Dołączył: 19.04.2009

Ostrzeżenie: (0%)
-----


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);



--------------------
Polecam MyDevil hosting idealny dla deweloperów
Go to the top of the page
+Quote Post
pela222
post
Post #9





Grupa: Zarejestrowani
Postów: 85
Pomógł: 0
Dołączył: 17.04.2013

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
bobek358
post
Post #10





Grupa: Zarejestrowani
Postów: 143
Pomógł: 22
Dołączył: 17.11.2007

Ostrzeżenie: (0%)
-----


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. }
Go to the top of the page
+Quote Post
pela222
post
Post #11





Grupa: Zarejestrowani
Postów: 85
Pomógł: 0
Dołączył: 17.04.2013

Ostrzeżenie: (0%)
-----


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.

Ten post edytował pela222 5.08.2015, 00:56:25
Go to the top of the page
+Quote Post
nospor
post
Post #12





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




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.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 20.08.2025 - 21:52