36    public static string $format = 
"Y-m-d H:i:s O";
 
   39    private \DateTime $creationDate;
 
   40    private string $source = 
"(Unknown)";
 
   41    private ?\DateTime $expirationDate = 
null;
 
   42    private string $reason = 
"Banned by an operator.";
 
   44    public function __construct(
string $name){
 
   45        $this->name = strtolower($name);
 
   47        $this->creationDate = new \DateTime();
 
   50    public function getName() : 
string{
 
   54    public function getCreated() : \DateTime{
 
   55        return $this->creationDate;
 
   62        self::validateDate($date);
 
   63        $this->creationDate = $date;
 
 
   66    public function getSource() : string{
 
   70    public function setSource(
string $source) : void{
 
   71        $this->source = $source;
 
   74    public function getExpires() : ?\DateTime{
 
   75        return $this->expirationDate;
 
   83            self::validateDate($date);
 
   85        $this->expirationDate = $date;
 
 
   88    public function hasExpired() : bool{
 
   90        $now = new \DateTime();
 
   92        return $this->expirationDate === 
null ? false : $this->expirationDate < $now;
 
   95    public function getReason() : string{
 
   99    public function setReason(
string $reason) : void{
 
  100        $this->reason = $reason;
 
  103    public function getString() : string{
 
  104        $expires = $this->getExpires();
 
  105        return implode(
"|", [
 
  107            $this->getCreated()->format(self::$format),
 
  109            $expires === 
null ? 
"Forever" : $expires->format(self::$format),
 
  122    private static function validateDate(\DateTime $dateTime) : void{
 
  124            self::parseDate($dateTime->format(self::$format));
 
  125        }
catch(\RuntimeException $e){
 
  126            throw new \InvalidArgumentException($e->getMessage(), 0, $e);
 
  133    private static function parseDate(
string $date) : \DateTime{
 
  134        $datetime = \DateTime::createFromFormat(self::$format, $date);
 
  135        if(!($datetime instanceof \DateTime)){
 
  136            $lastErrors = Utils::assumeNotFalse(\DateTime::getLastErrors(), 
"DateTime::getLastErrors() should not be returning false in here");
 
  137            throw new \RuntimeException(
"Corrupted date/time: " . implode(
", ", $lastErrors[
"errors"]));
 
  147        if(strlen($str) < 2){
 
  153        $parts = explode(
"|", trim($str), limit: 6);
 
  154        $entry = 
new BanEntry(trim(array_shift($parts)));
 
  155        if(count($parts) > 0){
 
  156            $entry->setCreated(self::parseDate(array_shift($parts)));
 
  158        if(count($parts) > 0){
 
  159            $entry->setSource(trim(array_shift($parts)));
 
  161        if(count($parts) > 0){
 
  162            $expire = trim(array_shift($parts));
 
  163            if($expire !== 
"" && strtolower($expire) !== 
"forever"){
 
  164                $entry->setExpires(self::parseDate($expire));
 
  167        if(count($parts) > 0){
 
  168            $entry->setReason(trim(array_shift($parts)));
 
 
 
setCreated(\DateTime $date)
 
static fromString(string $str)
 
setExpires(?\DateTime $date)