1: <?php
2:
3: namespace Charcoal\Cms\Support\Helpers;
4:
5:
6: use DateTime;
7: use Exception;
8:
9: use \Charcoal\Translator\TranslatorAwareTrait;
10:
11: 12: 13:
14: class DateHelper
15: {
16: use TranslatorAwareTrait;
17:
18: 19: 20:
21: protected $from;
22:
23: 24: 25:
26: protected $to;
27:
28: 29: 30:
31: protected $dateFormats;
32:
33: 34: 35:
36: protected $timeFormats;
37:
38: 39: 40:
41: protected $dateFormat;
42:
43: 44: 45:
46: protected $timeFormat;
47:
48: 49: 50: 51: 52:
53: public function __construct(array $data)
54: {
55: if (!isset($data['date_formats'])) {
56: throw new Exception('date formats configuration must be defined in the DateHelper constructor.');
57: }
58: if (!isset($data['time_formats'])) {
59: throw new Exception('time formats configuration must be defined in the DateHelper constructor.');
60: }
61: if (!isset($data['translator'])) {
62: throw new Exception('Translator needs to be defined in the dateHelper class.');
63: }
64:
65: $this->setTranslator($data['translator']);
66: $this->dateFormats = $data['date_formats'];
67: $this->timeFormats = $data['time_formats'];
68: }
69:
70: 71: 72: 73: 74: 75: 76: 77:
78: public function formatDate($date, $format = 'default')
79: {
80: $this->dateFormat = $format;
81:
82: if (is_array($date)) {
83: $this->from = $this->parseAsDate($date[0]);
84: $this->to = $this->parseAsDate($date[1]);
85: } else {
86: $this->from = $this->parseAsDate($date);
87: $this->to = null;
88: }
89:
90: return $this->formatDateFromCase($this->getDateCase());
91: }
92:
93: 94: 95: 96: 97: 98: 99: 100:
101: public function formatTime($date, $format = 'default')
102: {
103: $this->timeFormat = $format;
104:
105: if (is_array($date)) {
106: $this->from = $this->parseAsDate($date[0]);
107: $this->to = $this->parseAsDate($date[1]);
108: } else {
109: $this->from = $this->parseAsDate($date);
110: $this->to = null;
111: }
112:
113: return $this->formatTimeFromCase($this->getTimeCase());
114: }
115:
116: 117: 118: 119:
120: private function getDateCase()
121: {
122: $from = $this->from;
123: $to = $this->to;
124:
125:
126: if (!$to || $to->format('Ymd') === $from->format('Ymd')) {
127: return 'single';
128: }
129:
130: $fromDate = [
131: 'day' => $from->format('d'),
132: 'month' => $from->format('m'),
133: 'year' => $from->format('y')
134: ];
135:
136: $toDate = [
137: 'day' => $to->format('d'),
138: 'month' => $to->format('m'),
139: 'year' => $to->format('y')
140: ];
141:
142: $case = null;
143: $case = $fromDate['day'] !== $toDate['day'] ? 'different_day' : $case;
144: $case = $fromDate['month'] !== $toDate['month'] ? 'different_month' : $case;
145: $case = $fromDate['year'] !== $toDate['year'] ? 'different_year' : $case;
146:
147: return $case;
148: }
149:
150: 151: 152: 153:
154: private function getTimeCase()
155: {
156: $from = $this->from;
157: $to = $this->to;
158:
159:
160: if (!$to || $to->format('Hi') === $from->format('Hi')) {
161: if ($to->format('i') == 0) {
162: return 'single_round';
163: }
164:
165: return 'single';
166: }
167:
168: $fromTime = [
169: 'hour' => $from->format('H'),
170: 'minute' => $from->format('i'),
171: ];
172:
173: $toTime = [
174: 'hour' => $to->format('H'),
175: 'minute' => $to->format('i'),
176: ];
177:
178: $case = null;
179: $case = $fromTime['hour'] !== $toTime['hour'] ? 'different_time' : $case;
180: $case = $fromTime['minute'] == 0 ? 'different_time_round' : $case;
181: $case = $fromTime['minute'] != $toTime['minute'] ? 'different_time' : $case;
182:
183: return $case;
184: }
185:
186: 187: 188: 189:
190: private function formatDateFromCase($case)
191: {
192: $dateFormats = $this->dateFormats;
193: $case = $dateFormats[$this->dateFormat][$case];
194:
195: $content = $this->translator()->translation($case['content']);
196:
197: $formats['from'] = $this->translator()->translation($case['formats']['from']);
198: $formats['to'] = isset($case['formats']['to']) ? $this->translator()->translation($case['formats']['to']) : null;
199:
200: $formats['from'] = $this->crossPlatformFormat((string)$formats['from']);
201: $formats['to'] = $this->crossPlatformFormat((string)$formats['to']);
202:
203: if (!$this->to || !$formats['to']) {
204: return sprintf(
205: (string)$content,
206: strftime($formats['from'], $this->from->getTimestamp())
207: );
208: }
209:
210: return sprintf(
211: (string)$content,
212: strftime($formats['from'], $this->from->getTimestamp()),
213: strftime($formats['to'], $this->to->getTimestamp())
214: );
215: }
216:
217: 218: 219: 220:
221: private function formatTimeFromCase($case)
222: {
223: $timeFormats = $this->timeFormats;
224: $case = $timeFormats[$this->timeFormat][$case];
225:
226: $content = $this->translator()->translation($case['content']);
227:
228: $formats['from'] = $case['formats']['from'];
229: $formats['to'] = isset($case['formats']['to']) ? $case['formats']['to'] : null;
230:
231: $formats['from'] = $this->translator()->translation($formats['from']);
232: $formats['to'] = $this->translator()->translation($formats['to']);
233:
234: if (!$this->to || !$formats['to']) {
235: return sprintf(
236: (string)$content,
237: strftime($formats['from'], $this->from->getTimestamp())
238: );
239: }
240:
241: return sprintf(
242: (string)$content,
243: strftime($formats['from'], $this->from->getTimestamp()),
244: strftime($formats['to'], $this->to->getTimestamp())
245: );
246: }
247:
248:
249:
250:
251:
252: 253: 254: 255:
256: private function parseAsDate($date)
257: {
258: if ($date instanceof \DateTimeInterface) {
259: return $date;
260: }
261:
262: return new DateTime($date);
263: }
264:
265: 266: 267: 268:
269: private function crossPlatformFormat($format)
270: {
271: if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
272: $format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format);
273: }
274:
275: return $format;
276: }
277: }
278: