DatePoint.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Clock;
  11. /**
  12. * An immmutable DateTime with stricter error handling and return types than the native one.
  13. *
  14. * @author Nicolas Grekas <p@tchwork.com>
  15. */
  16. final class DatePoint extends \DateTimeImmutable
  17. {
  18. /**
  19. * @throws \DateMalformedStringException When $datetime is invalid
  20. */
  21. public function __construct(string $datetime = 'now', ?\DateTimeZone $timezone = null, ?parent $reference = null)
  22. {
  23. $now = $reference ?? Clock::get()->now();
  24. if ('now' !== $datetime) {
  25. if (!$now instanceof static) {
  26. $now = static::createFromInterface($now);
  27. }
  28. $builtInDate = new parent($datetime, $timezone ?? $now->getTimezone());
  29. $timezone = $builtInDate->getTimezone();
  30. $now = $now->setTimezone($timezone)->modify($datetime);
  31. if ('00:00:00.000000' === $builtInDate->format('H:i:s.u')) {
  32. $now = $now->setTime(0, 0);
  33. }
  34. } elseif (null !== $timezone) {
  35. $now = $now->setTimezone($timezone);
  36. }
  37. $this->__unserialize((array) $now);
  38. }
  39. /**
  40. * @throws \DateMalformedStringException When $format or $datetime are invalid
  41. */
  42. public static function createFromFormat(string $format, string $datetime, ?\DateTimeZone $timezone = null): static
  43. {
  44. return parent::createFromFormat($format, $datetime, $timezone) ?: throw new \DateMalformedStringException(static::getLastErrors()['errors'][0] ?? 'Invalid date string or format.');
  45. }
  46. public static function createFromInterface(\DateTimeInterface $object): static
  47. {
  48. return parent::createFromInterface($object);
  49. }
  50. public static function createFromMutable(\DateTime $object): static
  51. {
  52. return parent::createFromMutable($object);
  53. }
  54. public static function createFromTimestamp(int|float $timestamp): static
  55. {
  56. return parent::createFromTimestamp($timestamp);
  57. }
  58. public function add(\DateInterval $interval): static
  59. {
  60. return parent::add($interval);
  61. }
  62. public function sub(\DateInterval $interval): static
  63. {
  64. return parent::sub($interval);
  65. }
  66. /**
  67. * @throws \DateMalformedStringException When $modifier is invalid
  68. */
  69. public function modify(string $modifier): static
  70. {
  71. return parent::modify($modifier);
  72. }
  73. public function setTimestamp(int $value): static
  74. {
  75. return parent::setTimestamp($value);
  76. }
  77. public function setDate(int $year, int $month, int $day): static
  78. {
  79. return parent::setDate($year, $month, $day);
  80. }
  81. public function setISODate(int $year, int $week, int $day = 1): static
  82. {
  83. return parent::setISODate($year, $week, $day);
  84. }
  85. public function setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0): static
  86. {
  87. return parent::setTime($hour, $minute, $second, $microsecond);
  88. }
  89. public function setTimezone(\DateTimeZone $timezone): static
  90. {
  91. return parent::setTimezone($timezone);
  92. }
  93. public function getTimezone(): \DateTimeZone
  94. {
  95. return parent::getTimezone() ?: throw new \DateInvalidTimeZoneException('The DatePoint object has no timezone.');
  96. }
  97. public function setMicrosecond(int $microsecond): static
  98. {
  99. if ($microsecond < 0 || $microsecond > 999999) {
  100. throw new \DateRangeError('DatePoint::setMicrosecond(): Argument #1 ($microsecond) must be between 0 and 999999, '.$microsecond.' given');
  101. }
  102. return parent::setMicrosecond($microsecond);
  103. }
  104. }