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