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