Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
Date
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
8 / 8
14
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 __toString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setLanguage
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getLanguage
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 humanize
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
4
 jsonSerialize
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createFromFormat
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 createFromImmutable
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
1<?php declare(strict_types=1);
2/*
3 * This file is part of Aplus Framework Date Library.
4 *
5 * (c) Natan Felles <natanfelles@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10namespace Framework\Date;
11
12use DateTime;
13use DateTimeImmutable;
14use DateTimeZone;
15use Exception;
16use Framework\Language\Language;
17use JsonSerializable;
18use Stringable;
19
20/**
21 * Class Date.
22 *
23 * @see https://www.php.net/manual/en/intldateformatter.format.php#106070
24 * @see https://www.php.net/manual/en/intldateformatter.format.php#refsect1-intldateformatter.format-changelog
25 * @see https://www.php.net/manual/en/function.strftime.php
26 *
27 * @package date
28 */
29class Date extends DateTime implements JsonSerializable, Stringable
30{
31    public const DATETIME = 'Y-m-d H:i:s';
32    protected Language $language;
33
34    final public function __construct(
35        string $datetime = 'now',
36        DateTimeZone $timezone = null,
37        Language $language = null
38    ) {
39        parent::__construct($datetime, $timezone);
40        if ($language) {
41            $this->setLanguage($language);
42        }
43    }
44
45    public function __toString() : string
46    {
47        return $this->format(static::ATOM);
48    }
49
50    public function setLanguage(Language $language) : static
51    {
52        $this->language = $language;
53        $this->language->addDirectory(__DIR__ . '/Languages');
54        return $this;
55    }
56
57    public function getLanguage() : Language
58    {
59        if ( ! isset($this->language)) {
60            $this->setLanguage(new Language());
61        }
62        return $this->language;
63    }
64
65    public function humanize() : string
66    {
67        $timeDifference = $this->getTimestamp() - \time();
68        $language = $this->getLanguage();
69        $condition = [
70            12 * 30 * 24 * 60 * 60 => 'years',
71            30 * 24 * 60 * 60 => 'months',
72            7 * 24 * 60 * 60 => 'weeks',
73            24 * 60 * 60 => 'days',
74            60 * 60 => 'hours',
75            60 => 'minutes',
76            1 => 'seconds',
77        ];
78        $timing = 'in';
79        if ($timeDifference < 0) {
80            $timeDifference *= -1;
81            $timing = 'ago';
82        }
83        foreach ($condition as $seconds => $line) {
84            $diff = $timeDifference / $seconds;
85            if ($diff >= 1) {
86                $arg = \round($diff);
87                return $language->render('date', $timing, [
88                    $language->render('date', $line, [$arg]),
89                ]);
90            }
91        }
92        return $language->render('date', 'now');
93    }
94
95    public function jsonSerialize() : string
96    {
97        return $this->format(static::ATOM);
98    }
99
100    /**
101     * Parse a string into a new static object according to the specified format.
102     *
103     * @param string $format Format accepted by date()
104     * @param string $datetime A string representing the time
105     * @param DateTimeZone|null $timezone A DateTimeZone object representing the
106     * desired time zone
107     *
108     * @throws Exception Emits Exception in case of an error
109     *
110     * @return false|static
111     */
112    public static function createFromFormat(
113        $format,
114        $datetime,
115        DateTimeZone $timezone = null
116    ) : static | false {
117        $object = parent::createFromFormat($format, $datetime, $timezone);
118        return $object ? new static($object->format(static::ATOM)) : $object;
119    }
120
121    /**
122     * @param DateTimeImmutable $object
123     *
124     * @throws Exception Emits Exception in case of an error
125     *
126     * @return static
127     */
128    public static function createFromImmutable(DateTimeImmutable $object) : static
129    {
130        $object = parent::createFromImmutable($object);
131        return new static($object->format(static::ATOM));
132    }
133}