Avatar billede Slettet bruger
15. juni 2018 - 14:06 Der er 9 kommentarer

Finde korrekt årgang udfra fødselsdato

Hej eksperter,

Hvordan jeg få vist følgende U-årgange baseret på en persons fødselsdato?
U9 Årgang 2010 og yngre
U11 Årgang 2008 - 2009
U13 Årgang 2006 - 2007
U15 Årgang 2004 - 2005
U17 Årgang 2002 - 2003
U19 Årgang 2000 - 2001

Jeg har følgende kode pt. som fint viser personernes alder, men jeg vil gerne have vist årgangene ovenfor (fx U11) baseret på deres fødselsår.

PHP-kode:
if ($stmt = $conn->prepare("SELECT
      tm.id,
      tm.fornavn,
      tm.efternavn,
      tm.dob
    FROM tbl_medlem tm
    INNER JOIN tbl_map_medlem_hold tmmh
    ON tm.id = tmmh.medlem_id
    WHERE tmmh.hold_id = ? ORDER BY tm.fornavn, tm.efternavn")) {
      $stmt->bind_param("i", $hold);

      $stmt->execute();

      $stmt->bind_result($id, $fornavn, $efternavn, $dob);

      while ($stmt->fetch()){
        $member = array();
        $member['id'] = $id;
        $members_id[] = $id;
        $member['fornavn'] = $fornavn;
        $member['efternavn'] = $efternavn;

        # Calculate age       
        $today = new DateTime('today');
        $dob = new DateTime($dob);
        $age1 = $dob->diff($today)->y;
        $member['age'] = $age1;
       
        foreach($ages as $a){
          if($age >= $a['from'] && $age <= $a['to']){
            $member['age_group'] = $a['name'];
          }
        }
        $members[] = $member;
      }
      $stmt->close();
    }

Jeg håber der er nogen der kan hjælpe med noget fungerende kode :-)
På forhånd MANGE TAK :-)
Avatar billede acore Ekspert
15. juni 2018 - 14:16 #1
Er det KUN fødselsåret og det aktuelle år, der tilsammen afgør hvilket hold en spiller er på? Det er det, du skriver. men din kode bøvler også med alderen?
Avatar billede Slettet bruger
15. juni 2018 - 14:21 #2
Ja, det er det.
Fx U15 er personer der er født i perioden fra 01-01-2004 til 31-12-2005 (begge dage inkl.). Jeg skal umiddelbart ikke have vist deres alder, men kun U-årgangen.
Avatar billede Rune1983 Ekspert
15. juni 2018 - 14:53 #3
Ved ikke om jeg har forstået dit problem helt. Men kunne det ikke løses med en case i din sql?

SELECT
tm.id,
tm.fornavn,
tm.efternavn,
tm.dob,
CASE
    WHEN DATE_FORMAT(tm.dob, "%Y") < (DATE_FORMAT(CURDATE(), "%Y") - 8) THEN "U9 Årgang"
    WHEN DATE_FORMAT(tm.dob, "%Y") >= (DATE_FORMAT(CURDATE(), "%Y") - 10) AND DATE_FORMAT(tm.dob, "%Y") >= (DATE_FORMAT(CURDATE(), "%Y") - 9) THEN "U11 Årgang"
    ELSE "Gammel dreng"
END
AS 'Aargang'
FROM tbl_medlem tm
INNER JOIN tbl_map_medlem_hold tmmh
ON tm.id = tmmh.medlem_id
WHERE tmmh.hold_id = ? ORDER BY tm.fornavn, tm.efternavn
Avatar billede Rune1983 Ekspert
15. juni 2018 - 14:55 #4
Det kan godt være min større og mindre end lige skal rettes til. Det gik lidt hurtigt.
15. juni 2018 - 15:19 #5
Har / vil få samme problem, så jeg er med på en sidelinie !.

Kristian
Avatar billede Slettet bruger
15. juni 2018 - 16:08 #6
Jo det er ikke utænkeligt at det virker at tilpasse SQL'en, men hvordan vil du så printe/udskrive værdien? Pt. udskriver jeg bl.a. personens alder via følgende script:

<script type="text/javascript">
      $(document).ready(function () {
        $("#createMember").click(function(){
          var data = $("#memberForm").serialize();
          $.post("savemember.php", {'data': data}, function(json){
          });
        });

        $("#save_workouts").click(function(){
          var data = $("#myForm").serialize();
          $.post("savedata.php", {'data': data}, function(json){
          });
        });
       
        $("#team").change(function () {
          var team = $("#team").val();
          $.get( "json.php", {action: "members", hold: team}, function( data ) {

            var dates = '';
            $.each(data.dates, function (index, item) {
              dates += '<th class="dynamic_date">' + item.date + '</th>';
            });

            var tbody = '';
            var myVar = 1;
            $.each(data.members, function (index, item) {
              tbody += '<tr>';
              tbody += '<td align="left">' + myVar++ + '</td>';
              tbody += '<td align="left">' + '<a href="#myModal" data-toggle="modal" data-target="#edit-modal" id="' + item.id + '">' + item.fornavn + ' ' + item.efternavn +'</a></td>';
            tbody += '<td align="left">' + item.age + '</td>';
             
              $.each(item.workouts, function (index, date) {
                if(date.status){
                    tbody += '<td align="left" style="width:10%;"> <input type="checkbox" class="custom-control-input" name="member_'+item.id+'[]" value="'+date.date_id+'" checked></td>';
                  }else{
                    tbody += '<td align="left" style="width:10%;"> <input type="checkbox" class="custom-control-input" name="member_'+item.id+'[]" value="'+date.date_id+'"></td>';
                  }
              });

              tbody += '<td></td>';
              tbody += '</tr>';
            });

            $(".dynamic_date").remove();
            $(dates).insertBefore("#numbers_of");
            $('#myTable tbody').html(tbody);
          }, 'json');
        });
      });
    </script>
Avatar billede olsensweb.dk Ekspert
15. juni 2018 - 17:10 #7
>men jeg vil gerne have vist årgangene ovenfor (fx U11) baseret på deres fødselsår.
hvad indeholder $ages ??
er det ikke netop det du ligger ind i $member['age_group'] ??


foreach($ages as $a){
  if($age >= $a['from'] && $age <= $a['to']){
    $member['age_group'] = $a['name'];
  }
}


U9 Årgang
eller
U9
eller
9
eller ......

hvis den kun indeholde 9 må du kunne lave noget beregning med nuværende år - $member['age_group'].
og lave en sammensat string med "U".$member['age_group']  og noget logik til  2010 og yngre

din tabel kunne se ca sådan ud,
modificeret iforhold til https://www.computerworld.dk/eksperten/spm/1018647?k=8266687
CREATE TABLE `tbl_age_interval` (
  `id` int(11) NOT NULL, 
  `age_from` int(11) NOT NULL,
  `age_to` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci;

INSERT INTO `tbl_age_interval` (`id`, `age_from`, `age_to`) VALUES
(1, 0, 9),
(2, 10, 11),
(3, 12, 13),
(4, 14, 15),
(5, 16, 17),
(6, 18, 19);


"U".[age_to]."Årgang".beregning af årstal


har efterhånden misted overblikket over programmet efter
https://www.computerworld.dk/eksperten/spm/1018253?k=8264345
https://www.computerworld.dk/eksperten/spm/1018647?k=8266757


det ville være rart med test data, så vi ikke skal sidde og gætte på tabel structur, og indhold.
sql dump af relevante tabeller, med test data.


>Jeg håber der er nogen der kan hjælpe med noget fungerende kode :-)
dette er ikke en bestillings central, men hjælp til selvhjælp
det er dig der skal vedligeholde din code ikke os, ellers må du have fat i udvikleren af coden (muligvis mod betaling)
Avatar billede Slettet bruger
15. juni 2018 - 18:52 #8
Helt i orden, olsensweb.dk - Farvel og god aften...
Avatar billede arne_v Ekspert
17. juni 2018 - 04:18 #9
Umiddelbart tror jeg at det vil vaere langt nemmere hvis man starter med en god struktur.

Her er noget kode som viser en helt anden tilgang til problemet:


<?php
class U {
    public static $uarray = array('U9', 'U11', 'U13', 'U15', 'U17', 'U19');
    public static $baseyear = 2011;
}

class Medlem {
    private $id;
    private $fornavn;
    private $efternavn;
    private $dob;
    public function __construct($id, $fornavn, $efternavn, $dob) {
        $this->id = $id;
        $this->fornavn = $fornavn;
        $this->efternavn = $efternavn;
        $this->dob = $dob;
    }
    public function getId() {
        return $this->id;
    }
    public function getFornavn() {
        return $this->fornavn;
    }
    public function getEfternavn() {
        return $this->efternavn;
    }
    public function getDob() {
        return $this->dob;
    }
    public function getNavn() {
        return $this->fornavn . ' ' . $this->efternavn;
    }
    public function getU() {
        $dt = new DateTime($this->dob);
        $y = (int)$dt->format('Y');
        $u = U::$uarray[(U::$baseyear - $y) / 2];
        return $u;
    }
}

class MedlemsKartotek {
    private $list;
    public function __construct() {
        $this->list = array();
    }
    public function loadFromDatabase() {
        // simulation - should really load data from database
        $this->list[] = new Medlem(1, 'A', 'AA', '1-Jan-2009');
        $this->list[] = new Medlem(1, 'B', 'BB', '1-Feb-2008');
        $this->list[] = new Medlem(1, 'C', 'CC', '1-Mar-2005');
        $this->list[] = new Medlem(1, 'D', 'DD', '1-Apr-2004');
    }
    public function getAll() {
        return $this->list;
    }
    public function getU($u) {
        return array_filter($this->list, function($medlem) use($u) { return $medlem->getU() === $u; });
    }
}

class Formatter {
    public static function format($lbl, $list) {
        return sprintf("%s: %s", $lbl, array_reduce($list, function($accum, $medlem) { if(strlen($accum) > 0) $accum .= ','; return $accum .= $medlem->getNavn(); }, ''));
    }
}

$kartotek = new MedlemsKartotek();
$kartotek->loadFromDatabase();
echo Formatter::format('All', $kartotek->getAll()) . "\r\n";
foreach(U::$uarray as $u) {
    echo Formatter::format($u, $kartotek->getU($u)) . "\r\n";
}
?>

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

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