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