DateFactory.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <?php
  2. namespace Illuminate\Support;
  3. use Carbon\Factory;
  4. use InvalidArgumentException;
  5. /**
  6. * @see https://carbon.nesbot.com/docs/
  7. * @see https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Factory.php
  8. *
  9. * @method bool canBeCreatedFromFormat(?string $date, string $format)
  10. * @method \Illuminate\Support\Carbon|null create($year = 0, $month = 1, $day = 1, $hour = 0, $minute = 0, $second = 0, $timezone = null)
  11. * @method \Illuminate\Support\Carbon createFromDate($year = null, $month = null, $day = null, $timezone = null)
  12. * @method \Illuminate\Support\Carbon|null createFromFormat($format, $time, $timezone = null)
  13. * @method \Illuminate\Support\Carbon|null createFromIsoFormat(string $format, string $time, $timezone = null, ?string $locale = 'en', ?\Symfony\Contracts\Translation\TranslatorInterface $translator = null)
  14. * @method \Illuminate\Support\Carbon|null createFromLocaleFormat(string $format, string $locale, string $time, $timezone = null)
  15. * @method \Illuminate\Support\Carbon|null createFromLocaleIsoFormat(string $format, string $locale, string $time, $timezone = null)
  16. * @method \Illuminate\Support\Carbon createFromTime($hour = 0, $minute = 0, $second = 0, $timezone = null)
  17. * @method \Illuminate\Support\Carbon createFromTimeString(string $time, \DateTimeZone|string|int|null $timezone = null)
  18. * @method \Illuminate\Support\Carbon createFromTimestamp(string|int|float $timestamp, \DateTimeZone|string|int|null $timezone = null)
  19. * @method \Illuminate\Support\Carbon createFromTimestampMs(string|int|float $timestamp, \DateTimeZone|string|int|null $timezone = null)
  20. * @method \Illuminate\Support\Carbon createFromTimestampMsUTC($timestamp)
  21. * @method \Illuminate\Support\Carbon createFromTimestampUTC(string|int|float $timestamp)
  22. * @method \Illuminate\Support\Carbon createMidnightDate($year = null, $month = null, $day = null, $timezone = null)
  23. * @method \Illuminate\Support\Carbon|null createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $timezone = null)
  24. * @method \Illuminate\Support\Carbon createStrict(?int $year = 0, ?int $month = 1, ?int $day = 1, ?int $hour = 0, ?int $minute = 0, ?int $second = 0, $timezone = null)
  25. * @method void disableHumanDiffOption($humanDiffOption)
  26. * @method void enableHumanDiffOption($humanDiffOption)
  27. * @method mixed executeWithLocale(string $locale, callable $func)
  28. * @method \Illuminate\Support\Carbon fromSerialized($value)
  29. * @method array getAvailableLocales()
  30. * @method array getAvailableLocalesInfo()
  31. * @method array getDays()
  32. * @method ?string getFallbackLocale()
  33. * @method array getFormatsToIsoReplacements()
  34. * @method int getHumanDiffOptions()
  35. * @method array getIsoUnits()
  36. * @method array|false getLastErrors()
  37. * @method string getLocale()
  38. * @method int getMidDayAt()
  39. * @method string getTimeFormatByPrecision(string $unitPrecision)
  40. * @method string|\Closure|null getTranslationMessageWith($translator, string $key, ?string $locale = null, ?string $default = null)
  41. * @method \Illuminate\Support\Carbon|null getTestNow()
  42. * @method \Symfony\Contracts\Translation\TranslatorInterface getTranslator()
  43. * @method int getWeekEndsAt(?string $locale = null)
  44. * @method int getWeekStartsAt(?string $locale = null)
  45. * @method array getWeekendDays()
  46. * @method bool hasFormat(string $date, string $format)
  47. * @method bool hasFormatWithModifiers(string $date, string $format)
  48. * @method bool hasMacro($name)
  49. * @method bool hasRelativeKeywords(?string $time)
  50. * @method bool hasTestNow()
  51. * @method \Illuminate\Support\Carbon instance(\DateTimeInterface $date)
  52. * @method bool isImmutable()
  53. * @method bool isModifiableUnit($unit)
  54. * @method bool isMutable()
  55. * @method bool isStrictModeEnabled()
  56. * @method bool localeHasDiffOneDayWords(string $locale)
  57. * @method bool localeHasDiffSyntax(string $locale)
  58. * @method bool localeHasDiffTwoDayWords(string $locale)
  59. * @method bool localeHasPeriodSyntax($locale)
  60. * @method bool localeHasShortUnits(string $locale)
  61. * @method void macro(string $name, ?callable $macro)
  62. * @method \Illuminate\Support\Carbon|null make($var, \DateTimeZone|string|null $timezone = null)
  63. * @method void mixin(object|string $mixin)
  64. * @method \Illuminate\Support\Carbon now(\DateTimeZone|string|int|null $timezone = null)
  65. * @method \Illuminate\Support\Carbon parse(\DateTimeInterface|\Carbon\WeekDay|\Carbon\Month|string|int|float|null $time, \DateTimeZone|string|int|null $timezone = null)
  66. * @method \Illuminate\Support\Carbon parseFromLocale(string $time, ?string $locale = null, \DateTimeZone|string|int|null $timezone = null)
  67. * @method string pluralUnit(string $unit)
  68. * @method \Illuminate\Support\Carbon|null rawCreateFromFormat(string $format, string $time, $timezone = null)
  69. * @method \Illuminate\Support\Carbon rawParse(\DateTimeInterface|\Carbon\WeekDay|\Carbon\Month|string|int|float|null $time, \DateTimeZone|string|int|null $timezone = null)
  70. * @method void resetMonthsOverflow()
  71. * @method void resetToStringFormat()
  72. * @method void resetYearsOverflow()
  73. * @method void serializeUsing($callback)
  74. * @method void setFallbackLocale(string $locale)
  75. * @method void setHumanDiffOptions($humanDiffOptions)
  76. * @method void setLocale(string $locale)
  77. * @method void setMidDayAt($hour)
  78. * @method void setTestNow(mixed $testNow = null)
  79. * @method void setTestNowAndTimezone(mixed $testNow = null, $timezone = null)
  80. * @method void setToStringFormat(string|\Closure|null $format)
  81. * @method void setTranslator(\Symfony\Contracts\Translation\TranslatorInterface $translator)
  82. * @method void setWeekEndsAt($day)
  83. * @method void setWeekStartsAt($day)
  84. * @method void setWeekendDays($days)
  85. * @method bool shouldOverflowMonths()
  86. * @method bool shouldOverflowYears()
  87. * @method string singularUnit(string $unit)
  88. * @method void sleep(int|float $seconds)
  89. * @method \Illuminate\Support\Carbon today(\DateTimeZone|string|int|null $timezone = null)
  90. * @method \Illuminate\Support\Carbon tomorrow(\DateTimeZone|string|int|null $timezone = null)
  91. * @method string translateTimeString(string $timeString, ?string $from = null, ?string $to = null, int $mode = \Carbon\CarbonInterface::TRANSLATE_ALL)
  92. * @method string translateWith(\Symfony\Contracts\Translation\TranslatorInterface $translator, string $key, array $parameters = [], $number = null)
  93. * @method void useMonthsOverflow($monthsOverflow = true)
  94. * @method void useStrictMode($strictModeEnabled = true)
  95. * @method void useYearsOverflow($yearsOverflow = true)
  96. * @method mixed withTestNow(mixed $testNow, callable $callback)
  97. * @method static withTimeZone(\DateTimeZone|string|int|null $timezone)
  98. * @method \Illuminate\Support\Carbon yesterday(\DateTimeZone|string|int|null $timezone = null)
  99. */
  100. class DateFactory
  101. {
  102. /**
  103. * The default class that will be used for all created dates.
  104. *
  105. * @var string
  106. */
  107. const DEFAULT_CLASS_NAME = Carbon::class;
  108. /**
  109. * The type (class) of dates that should be created.
  110. *
  111. * @var string
  112. */
  113. protected static $dateClass;
  114. /**
  115. * This callable may be used to intercept date creation.
  116. *
  117. * @var callable
  118. */
  119. protected static $callable;
  120. /**
  121. * The Carbon factory that should be used when creating dates.
  122. *
  123. * @var object
  124. */
  125. protected static $factory;
  126. /**
  127. * Use the given handler when generating dates (class name, callable, or factory).
  128. *
  129. * @param mixed $handler
  130. * @return mixed
  131. *
  132. * @throws \InvalidArgumentException
  133. */
  134. public static function use($handler)
  135. {
  136. if (is_callable($handler) && is_object($handler)) {
  137. return static::useCallable($handler);
  138. } elseif (is_string($handler)) {
  139. return static::useClass($handler);
  140. } elseif ($handler instanceof Factory) {
  141. return static::useFactory($handler);
  142. }
  143. throw new InvalidArgumentException('Invalid date creation handler. Please provide a class name, callable, or Carbon factory.');
  144. }
  145. /**
  146. * Use the default date class when generating dates.
  147. *
  148. * @return void
  149. */
  150. public static function useDefault()
  151. {
  152. static::$dateClass = null;
  153. static::$callable = null;
  154. static::$factory = null;
  155. }
  156. /**
  157. * Execute the given callable on each date creation.
  158. *
  159. * @param callable $callable
  160. * @return void
  161. */
  162. public static function useCallable(callable $callable)
  163. {
  164. static::$callable = $callable;
  165. static::$dateClass = null;
  166. static::$factory = null;
  167. }
  168. /**
  169. * Use the given date type (class) when generating dates.
  170. *
  171. * @param string $dateClass
  172. * @return void
  173. */
  174. public static function useClass($dateClass)
  175. {
  176. static::$dateClass = $dateClass;
  177. static::$factory = null;
  178. static::$callable = null;
  179. }
  180. /**
  181. * Use the given Carbon factory when generating dates.
  182. *
  183. * @param object $factory
  184. * @return void
  185. */
  186. public static function useFactory($factory)
  187. {
  188. static::$factory = $factory;
  189. static::$dateClass = null;
  190. static::$callable = null;
  191. }
  192. /**
  193. * Handle dynamic calls to generate dates.
  194. *
  195. * @param string $method
  196. * @param array $parameters
  197. * @return mixed
  198. *
  199. * @throws \RuntimeException
  200. */
  201. public function __call($method, $parameters)
  202. {
  203. $defaultClassName = static::DEFAULT_CLASS_NAME;
  204. // Using callable to generate dates...
  205. if (static::$callable) {
  206. return call_user_func(static::$callable, $defaultClassName::$method(...$parameters));
  207. }
  208. // Using Carbon factory to generate dates...
  209. if (static::$factory) {
  210. return static::$factory->$method(...$parameters);
  211. }
  212. $dateClass = static::$dateClass ?: $defaultClassName;
  213. // Check if the date can be created using the public class method...
  214. if (method_exists($dateClass, $method) ||
  215. method_exists($dateClass, 'hasMacro') && $dateClass::hasMacro($method)) {
  216. return $dateClass::$method(...$parameters);
  217. }
  218. // If that fails, create the date with the default class...
  219. $date = $defaultClassName::$method(...$parameters);
  220. // If the configured class has an "instance" method, we'll try to pass our date into there...
  221. if (method_exists($dateClass, 'instance')) {
  222. return $dateClass::instance($date);
  223. }
  224. // Otherwise, assume the configured class has a DateTime compatible constructor...
  225. return new $dateClass($date->format('Y-m-d H:i:s.u'), $date->getTimezone());
  226. }
  227. }