DateFactory.php 7.8 KB

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