xref: /webtrees/app/Timestamp.php (revision 8634febf6487fcb3ee7b59e88f828071a22cba22)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2023 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees;
21
22use Carbon\Carbon;
23use DateInterval;
24use Fisharebest\Webtrees\Contracts\TimestampInterface;
25
26/**
27 * A localized date-time.
28 */
29class Timestamp implements TimestampInterface
30{
31    private Carbon $carbon;
32
33    /**
34     * @param int    $timestamp
35     * @param string $timezone
36     * @param string $locale
37     */
38    public function __construct(int $timestamp, string $timezone, string $locale)
39    {
40        $this->carbon = Carbon::createFromTimestamp($timestamp, $timezone);
41        $this->carbon->locale($locale);
42    }
43
44    /**
45     * Convert a datetime to the user's Julian day number.
46     *
47     * @return int
48     */
49    public function julianDay(): int
50    {
51        return gregoriantojd($this->carbon->month, $this->carbon->day, $this->carbon->year);
52    }
53
54    /**
55     * @return string
56     */
57    public function diffForHumans(): string
58    {
59        return $this->carbon->diffForHumans();
60    }
61
62    /**
63     * @param string $format
64     *
65     * @return string
66     */
67    public function format(string $format): string
68    {
69        return $this->carbon->format($format);
70    }
71
72    /**
73     * @param string $format
74     *
75     * @return string
76     */
77    public function isoFormat(string $format): string
78    {
79        return $this->carbon->isoFormat($format);
80    }
81
82    /**
83     * @return string
84     */
85    public function toDateString(): string
86    {
87        return $this->carbon->format('Y-m-d');
88    }
89
90    /**
91     * @return string
92     */
93    public function toDateTimeString(): string
94    {
95        return $this->carbon->format('Y-m-d H:i:s');
96    }
97
98    /**
99     * @param TimestampInterface $datetime
100     *
101     * @return int
102     */
103    public function compare(TimestampInterface $datetime): int
104    {
105        if ($this->carbon->lt($datetime)) {
106            return -1;
107        }
108
109        if ($this->carbon->gt($datetime)) {
110            return 1;
111        }
112
113        return 0;
114    }
115
116    /**
117     * @param int $seconds
118     *
119     * @return self
120     */
121    public function addSeconds(int $seconds): TimestampInterface
122    {
123        if ($seconds < 0) {
124            return $this->subtractSeconds(-$seconds);
125        }
126
127        $clone = clone($this);
128
129        $clone->carbon->add(new DateInterval('PT' . $seconds . 'S'));
130
131        return $clone;
132    }
133
134    /**
135     * @param int $minutes
136     *
137     * @return self
138     */
139    public function addMinutes(int $minutes): TimestampInterface
140    {
141        if ($minutes < 0) {
142            return $this->subtractMinutes(-$minutes);
143        }
144
145        $clone = clone($this);
146
147        $clone->carbon->add(new DateInterval('PT' . $minutes . 'M'));
148
149        return $this;
150    }
151
152    /**
153     * @param int $hours
154     *
155     * @return self
156     */
157    public function addHours(int $hours): TimestampInterface
158    {
159        if ($hours < 0) {
160            return $this->subtractHours(-$hours);
161        }
162
163        $clone = clone($this);
164
165        $clone->carbon->add(new DateInterval('PT' . $hours . 'H'));
166
167        return $clone;
168    }
169
170    /**
171     * @param int $days
172     *
173     * @return self
174     */
175    public function addDays(int $days): TimestampInterface
176    {
177        if ($days < 0) {
178            return $this->subtractHours(-$days);
179        }
180
181        $clone = clone($this);
182
183        $clone->carbon->add(new DateInterval('P' . $days . 'D'));
184
185        return $clone;
186    }
187
188    /**
189     * @param int $months
190     *
191     * @return self
192     */
193    public function addMonths(int $months): TimestampInterface
194    {
195        if ($months < 0) {
196            return $this->subtractMonths(-$months);
197        }
198
199        $clone = clone($this);
200
201        $clone->carbon->add(new DateInterval('P' . $months . 'M'));
202
203        return $clone;
204    }
205
206    /**
207     * @param int $years
208     *
209     * @return self
210     */
211    public function addYears(int $years): TimestampInterface
212    {
213        if ($years < 0) {
214            return $this->subtractYears(-$years);
215        }
216
217        $clone = clone($this);
218
219        $clone->carbon->add(new DateInterval('P' . $years . 'Y'));
220
221        return $clone;
222    }
223
224    /**
225     * @param int $seconds
226     *
227     * @return self
228     */
229    public function subtractSeconds(int $seconds): TimestampInterface
230    {
231        if ($seconds < 0) {
232            return $this->addSeconds(-$seconds);
233        }
234
235        $clone = clone($this);
236
237        $clone->carbon->sub(new DateInterval('PT' . $seconds . 'S'));
238
239        return $clone;
240    }
241
242    /**
243     * @param int $minutes
244     *
245     * @return self
246     */
247    public function subtractMinutes(int $minutes): TimestampInterface
248    {
249        if ($minutes < 0) {
250            return $this->addMinutes(-$minutes);
251        }
252
253        $clone = clone($this);
254
255        $clone->carbon->sub(new DateInterval('PT' . $minutes . 'M'));
256
257        return $clone;
258    }
259
260    /**
261     * @param int $hours
262     *
263     * @return self
264     */
265    public function subtractHours(int $hours): TimestampInterface
266    {
267        if ($hours < 0) {
268            return $this->addHours(-$hours);
269        }
270
271        $clone = clone($this);
272
273        $clone->carbon->sub(new DateInterval('PT' . $hours . 'H'));
274
275        return $clone;
276    }
277
278    /**
279     * @param int $days
280     *
281     * @return self
282     */
283    public function subtractDays(int $days): TimestampInterface
284    {
285        if ($days < 0) {
286            return $this->addDays(-$days);
287        }
288
289        $clone = clone($this);
290
291        $clone->carbon->sub(new DateInterval('P' . $days . 'D'));
292
293        return $clone;
294    }
295
296    /**
297     * @param int $months
298     *
299     * @return self
300     */
301    public function subtractMonths(int $months): TimestampInterface
302    {
303        if ($months < 0) {
304            return $this->addMonths(-$months);
305        }
306
307        $clone = clone($this);
308
309        $clone->carbon->sub(new DateInterval('P' . $months . 'M'));
310
311        return $clone;
312    }
313
314    /**
315     * @param int $years
316     *
317     * @return self
318     */
319    public function subtractYears(int $years): TimestampInterface
320    {
321        if ($years < 0) {
322            return $this->addYears(-$years);
323        }
324
325        $clone = clone($this);
326
327        $clone->carbon->sub(new DateInterval('P' . $years . 'Y'));
328
329        return $clone;
330    }
331
332    /**
333     * @return int
334     */
335    public function timestamp(): int
336    {
337        return $this->carbon->getTimestamp();
338    }
339}
340