lowerBound = $lowerBound; $this->upperBound = $upperBound; $this->lowerClosed = $lowerClosed; $this->upperClosed = $upperClosed; } function __toString(): string { return ($this->lowerClosed ? "[" : "(") . $this->lowerBound . ", " . $this->upperBound . ($this->upperClosed ? "]" : ")"); } function contains($value) { return ($this->lowerClosed ? $this->lowerBound <= $value : $this->lowerBound < $value) && ($this->upperClosed ? $value <= $this->upperBound : $value < $this->upperBound); } // private member //- variables // upper/lower bounds for the interval private $lowerBound; private $upperBound; // on true the bound is in the interval, otherwise not private $lowerClosed; private $upperClosed; } // data type for an age class class AgeGroup { // public member // - functions function __construct(string $label, Interval $years) { $this->label = $label; $this->years = $years; } function __toString(): string { return $this->label . " " . $this->years; } function years() { return $this->years; } /** factory method for AgeGroup-s * * @param [string] $label string denoting the AgeGroup * @param [type] $year the year to reference the AgeGroup to * @return AgeGroup interval of years of the age group */ public static function create(string $label, ?int $year = null) { // input sanitation $year = filterPosInt($year) ?? filterPosInt((new DateTime())->format("Y")); $lowerYear = null; $upperYear = null; // Matching against the different age class formats // - ..Ux // - Jg.x-y // Case Ux $akUmatchString = "/(.*)U([0-9]+)(.*)/"; $matches = []; preg_match($akUmatchString, $label, $matches); // The found match should cover the whole string. Otherwise it isn't applicable. if ($matches[0] == $label) { // The x in Ux should be a positive integer. $ageLimit = filterPosInt($matches[2]); if ($ageLimit) { $lowerYear = $year - $ageLimit + 1; // lowering the lower bound according to the modifiers if ($matches[3] == "") { $upperYear = $year - $ageLimit + 2; } elseif ($matches[3] == "-") { $upperYear = $year - $ageLimit + 3; } elseif ($matches[3] == "--") { $upperYear = $year - $ageLimit + 4; } elseif ( in_array($matches[1], [ "<=", "≤", "≤", "≤", "≤", ]) ) { $upperYear = $year; } return new AgeGroup( $label, new Interval($lowerYear, $upperYear, true, true) ); } } // Case Jg.x-y $akUmatchString = "/Jg\.(.*)\-{1,2}(.*)/"; $matches = []; preg_match($akUmatchString, $label, $matches); // The found match should cover the whole string. Otherwise it isn't applicable. if ($matches[0] == $label) { $lowerYear = filterPosInt($matches[1]); $upperYear = filterPosInt($matches[2]); return new AgeGroup( $label, new Interval($lowerYear, $upperYear, true, true) ); } return new AgeGroup( $label, new Interval($lowerYear, $upperYear, true, true) ); } // private member // - functions // - variables private $label; private $years; }