Completed
Push — master ( 70b2c3...e706ac )
by Peter
04:34
created

Formatter::format()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 31
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 31
ccs 22
cts 22
cp 1
rs 8.439
cc 6
eloc 20
nc 6
nop 2
crap 6
1
<?php
2
/**
3
 * GpsLab component.
4
 *
5
 * @author    Peter Gribanov <[email protected]>
6
 * @copyright Copyright (c) 2016, Peter Gribanov
7
 * @license   http://opensource.org/licenses/MIT
8
 */
9
10
namespace GpsLab\Bundle\DateBundle;
11
12
use Symfony\Component\Translation\TranslatorInterface;
13
14
class Formatter
15
{
16
    /**
17
     * @var string
18
     */
19
    const DEFAULT_PASSED_TIME_FORMAT = 'H:i';
20
    const DEFAULT_PASSED_MONTH_FORMAT = 'd f \a\t H:i';
21
    const DEFAULT_PASSED_YEAR_FORMAT = 'd f Y \a\t H:i';
22
23
    /**
24
     * @var TranslatorInterface
25
     */
26
    protected $translator;
27
28
    /**
29
     * @var array
30
     */
31
    protected $trans_format = [
32
        'f' => ['F', 'month.genitive.%s'],
33
        'D' => ['l', 'weekday.short.%s'],
34
        'l' => ['l', 'weekday.long.%s'],
35
        'F' => ['F', 'month.long.%s'],
36
        'M' => ['F', 'month.short.%s'],
37
    ];
38
39
    /**
40
     * @param TranslatorInterface $translator
41
     */
42 29
    public function __construct(TranslatorInterface $translator)
43
    {
44 29
        $this->translator = $translator;
45 29
    }
46
47
    /**
48
     * Format date.
49
     *
50
     * @see date()
51
     *
52
     * Additional:
53
     * f - Full name of the month, such as 'января' or 'марта' of January through December
54
     *
55
     * @param \DateTime $date
56
     * @param string $format
57
     *
58
     * @return string
59
     */
60 27
    public function format(\DateTime $date, $format)
61
    {
62 27
        $result = '';
63 27
        $escape = false;
64 27
        $length = strlen($format);
65
66 27
        for ($pos = 0; $pos < $length; ++$pos) {
67 27
            $char = mb_substr($format, $pos, 1, 'UTF-8');
68
69 27
            if ($char == '\\') {
70 9
                if ($escape) {
71 4
                    $result .= $char;
72 4
                }
73 9
                $escape = !$escape;
74 9
                continue;
75
            }
76
77 27
            if ($escape) { // escaped character
78 7
                $result .= $char;
79 27
            } elseif (isset($this->trans_format[$char])) {
80 8
                list($char, $trans) = $this->trans_format[$char];
81 8
                $result .= $this->trans(sprintf($trans, strtolower($date->format($char))));
82 8
            } else {
83 17
                $result .= $date->format($char);
84
            }
85
86 27
            $escape = false;
87 27
        }
88
89 27
        return $result;
90
    }
91
92
    /**
93
     * Passed date, such as 'X minutes ago', 'In X minutes', 'Today at X', 'Yesterday at X' or 'Tomorrow at X'.
94
     *
95
     * @param \DateTime $date
96
     * @param string $time_format
97
     * @param string $month_format
98
     * @param string $year_format
99
     *
100
     * @return string
101
     */
102 7
    public function passed(
103
        \DateTime $date,
104
        $time_format = self::DEFAULT_PASSED_TIME_FORMAT,
105
        $month_format = self::DEFAULT_PASSED_MONTH_FORMAT,
106
        $year_format = self::DEFAULT_PASSED_YEAR_FORMAT
107
    ) {
108 7
        $today = new \DateTime('now', $date->getTimezone());
109 7
        $yesterday = new \DateTime('-1 day', $date->getTimezone());
110 7
        $tomorrow = new \DateTime('+1 day', $date->getTimezone());
111 7
        $minutes_ago = round(($today->format('U') - $date->format('U')) / 60);
112 7
        $minutes_in = round(($date->format('U') - $today->format('U')) / 60);
113
114 7
        if ($minutes_ago > 0 && $minutes_ago < 60) {
115 1
            return $this->trans('passed.minutes_ago', ['%minutes%' => $minutes_ago]);
116 6
        } elseif ($minutes_in > 0 && $minutes_in < 60) {
117 1
            return $this->trans('passed.in_minutes', ['%minutes%' => $minutes_in]);
118 5
        } elseif ($today->format('ymd') == $date->format('ymd')) {
119 1
            return $this->trans('passed.today', ['%time%' => $this->format($date, $time_format)]);
120 4
        } elseif ($yesterday->format('ymd') == $date->format('ymd')) {
121 1
            return $this->trans('passed.yesterday', ['%time%' => $this->format($date, $time_format)]);
122 3
        } elseif ($tomorrow->format('ymd') == $date->format('ymd')) {
123 1
            return $this->trans('passed.tomorrow', ['%time%' => $this->format($date, $time_format)]);
124 2
        } elseif ($today->format('Y') == $date->format('Y')) {
125 1
            return $this->format($date, $month_format);
126
        } else {
127 1
            return $this->format($date, $year_format);
128
        }
129
    }
130
131
    /**
132
     * @param string $id
133
     * @param array $parameters
134
     *
135
     * @return string
136
     */
137 13
    private function trans($id, array $parameters = [])
138
    {
139 13
        return $this->translator->trans($id, $parameters, 'date');
140
    }
141
}
142