Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/**
4
 * This file is part of the Carbon package.
5
 *
6
 * (c) Brian Nesbitt <brian@nesbot.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Carbon\Traits;
13
 
14
use Carbon\CarbonInterface;
15
use ReturnTypeWillChange;
16
 
17
/**
18
 * Trait Modifiers.
19
 *
20
 * Returns dates relative to current date using modifier short-hand.
21
 */
22
trait Modifiers
23
{
24
    /**
25
     * Midday/noon hour.
26
     *
27
     * @var int
28
     */
29
    protected static $midDayAt = 12;
30
 
31
    /**
32
     * get midday/noon hour
33
     *
34
     * @return int
35
     */
36
    public static function getMidDayAt()
37
    {
38
        return static::$midDayAt;
39
    }
40
 
41
    /**
42
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
43
     *             You should rather consider mid-day is always 12pm, then if you need to test if it's an other
44
     *             hour, test it explicitly:
45
     *                 $date->format('G') == 13
46
     *             or to set explicitly to a given hour:
47
     *                 $date->setTime(13, 0, 0, 0)
48
     *
49
     * Set midday/noon hour
50
     *
51
     * @param int $hour midday hour
52
     *
53
     * @return void
54
     */
55
    public static function setMidDayAt($hour)
56
    {
57
        static::$midDayAt = $hour;
58
    }
59
 
60
    /**
61
     * Modify to midday, default to self::$midDayAt
62
     *
63
     * @return static
64
     */
65
    public function midDay()
66
    {
67
        return $this->setTime(static::$midDayAt, 0, 0, 0);
68
    }
69
 
70
    /**
71
     * Modify to the next occurrence of a given modifier such as a day of
72
     * the week. If no modifier is provided, modify to the next occurrence
73
     * of the current day of the week. Use the supplied constants
74
     * to indicate the desired dayOfWeek, ex. static::MONDAY.
75
     *
76
     * @param string|int|null $modifier
77
     *
78
     * @return static|false
79
     */
80
    public function next($modifier = null)
81
    {
82
        if ($modifier === null) {
83
            $modifier = $this->dayOfWeek;
84
        }
85
 
86
        return $this->change(
87
            'next '.(\is_string($modifier) ? $modifier : static::$days[$modifier])
88
        );
89
    }
90
 
91
    /**
92
     * Go forward or backward to the next week- or weekend-day.
93
     *
94
     * @param bool $weekday
95
     * @param bool $forward
96
     *
97
     * @return static
98
     */
99
    private function nextOrPreviousDay($weekday = true, $forward = true)
100
    {
101
        /** @var CarbonInterface $date */
102
        $date = $this;
103
        $step = $forward ? 1 : -1;
104
 
105
        do {
106
            $date = $date->addDays($step);
107
        } while ($weekday ? $date->isWeekend() : $date->isWeekday());
108
 
109
        return $date;
110
    }
111
 
112
    /**
113
     * Go forward to the next weekday.
114
     *
115
     * @return static
116
     */
117
    public function nextWeekday()
118
    {
119
        return $this->nextOrPreviousDay();
120
    }
121
 
122
    /**
123
     * Go backward to the previous weekday.
124
     *
125
     * @return static
126
     */
127
    public function previousWeekday()
128
    {
129
        return $this->nextOrPreviousDay(true, false);
130
    }
131
 
132
    /**
133
     * Go forward to the next weekend day.
134
     *
135
     * @return static
136
     */
137
    public function nextWeekendDay()
138
    {
139
        return $this->nextOrPreviousDay(false);
140
    }
141
 
142
    /**
143
     * Go backward to the previous weekend day.
144
     *
145
     * @return static
146
     */
147
    public function previousWeekendDay()
148
    {
149
        return $this->nextOrPreviousDay(false, false);
150
    }
151
 
152
    /**
153
     * Modify to the previous occurrence of a given modifier such as a day of
154
     * the week. If no dayOfWeek is provided, modify to the previous occurrence
155
     * of the current day of the week. Use the supplied constants
156
     * to indicate the desired dayOfWeek, ex. static::MONDAY.
157
     *
158
     * @param string|int|null $modifier
159
     *
160
     * @return static|false
161
     */
162
    public function previous($modifier = null)
163
    {
164
        if ($modifier === null) {
165
            $modifier = $this->dayOfWeek;
166
        }
167
 
168
        return $this->change(
169
            'last '.(\is_string($modifier) ? $modifier : static::$days[$modifier])
170
        );
171
    }
172
 
173
    /**
174
     * Modify to the first occurrence of a given day of the week
175
     * in the current month. If no dayOfWeek is provided, modify to the
176
     * first day of the current month.  Use the supplied constants
177
     * to indicate the desired dayOfWeek, ex. static::MONDAY.
178
     *
179
     * @param int|null $dayOfWeek
180
     *
181
     * @return static
182
     */
183
    public function firstOfMonth($dayOfWeek = null)
184
    {
185
        $date = $this->startOfDay();
186
 
187
        if ($dayOfWeek === null) {
188
            return $date->day(1);
189
        }
190
 
191
        return $date->modify('first '.static::$days[$dayOfWeek].' of '.$date->rawFormat('F').' '.$date->year);
192
    }
193
 
194
    /**
195
     * Modify to the last occurrence of a given day of the week
196
     * in the current month. If no dayOfWeek is provided, modify to the
197
     * last day of the current month.  Use the supplied constants
198
     * to indicate the desired dayOfWeek, ex. static::MONDAY.
199
     *
200
     * @param int|null $dayOfWeek
201
     *
202
     * @return static
203
     */
204
    public function lastOfMonth($dayOfWeek = null)
205
    {
206
        $date = $this->startOfDay();
207
 
208
        if ($dayOfWeek === null) {
209
            return $date->day($date->daysInMonth);
210
        }
211
 
212
        return $date->modify('last '.static::$days[$dayOfWeek].' of '.$date->rawFormat('F').' '.$date->year);
213
    }
214
 
215
    /**
216
     * Modify to the given occurrence of a given day of the week
217
     * in the current month. If the calculated occurrence is outside the scope
218
     * of the current month, then return false and no modifications are made.
219
     * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
220
     *
221
     * @param int $nth
222
     * @param int $dayOfWeek
223
     *
224
     * @return mixed
225
     */
226
    public function nthOfMonth($nth, $dayOfWeek)
227
    {
228
        $date = $this->avoidMutation()->firstOfMonth();
229
        $check = $date->rawFormat('Y-m');
230
        $date = $date->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
231
 
232
        return $date->rawFormat('Y-m') === $check ? $this->modify((string) $date) : false;
233
    }
234
 
235
    /**
236
     * Modify to the first occurrence of a given day of the week
237
     * in the current quarter. If no dayOfWeek is provided, modify to the
238
     * first day of the current quarter.  Use the supplied constants
239
     * to indicate the desired dayOfWeek, ex. static::MONDAY.
240
     *
241
     * @param int|null $dayOfWeek day of the week default null
242
     *
243
     * @return static
244
     */
245
    public function firstOfQuarter($dayOfWeek = null)
246
    {
247
        return $this->setDate($this->year, $this->quarter * static::MONTHS_PER_QUARTER - 2, 1)->firstOfMonth($dayOfWeek);
248
    }
249
 
250
    /**
251
     * Modify to the last occurrence of a given day of the week
252
     * in the current quarter. If no dayOfWeek is provided, modify to the
253
     * last day of the current quarter.  Use the supplied constants
254
     * to indicate the desired dayOfWeek, ex. static::MONDAY.
255
     *
256
     * @param int|null $dayOfWeek day of the week default null
257
     *
258
     * @return static
259
     */
260
    public function lastOfQuarter($dayOfWeek = null)
261
    {
262
        return $this->setDate($this->year, $this->quarter * static::MONTHS_PER_QUARTER, 1)->lastOfMonth($dayOfWeek);
263
    }
264
 
265
    /**
266
     * Modify to the given occurrence of a given day of the week
267
     * in the current quarter. If the calculated occurrence is outside the scope
268
     * of the current quarter, then return false and no modifications are made.
269
     * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
270
     *
271
     * @param int $nth
272
     * @param int $dayOfWeek
273
     *
274
     * @return mixed
275
     */
276
    public function nthOfQuarter($nth, $dayOfWeek)
277
    {
278
        $date = $this->avoidMutation()->day(1)->month($this->quarter * static::MONTHS_PER_QUARTER);
279
        $lastMonth = $date->month;
280
        $year = $date->year;
281
        $date = $date->firstOfQuarter()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
282
 
283
        return ($lastMonth < $date->month || $year !== $date->year) ? false : $this->modify((string) $date);
284
    }
285
 
286
    /**
287
     * Modify to the first occurrence of a given day of the week
288
     * in the current year. If no dayOfWeek is provided, modify to the
289
     * first day of the current year.  Use the supplied constants
290
     * to indicate the desired dayOfWeek, ex. static::MONDAY.
291
     *
292
     * @param int|null $dayOfWeek day of the week default null
293
     *
294
     * @return static
295
     */
296
    public function firstOfYear($dayOfWeek = null)
297
    {
298
        return $this->month(1)->firstOfMonth($dayOfWeek);
299
    }
300
 
301
    /**
302
     * Modify to the last occurrence of a given day of the week
303
     * in the current year. If no dayOfWeek is provided, modify to the
304
     * last day of the current year.  Use the supplied constants
305
     * to indicate the desired dayOfWeek, ex. static::MONDAY.
306
     *
307
     * @param int|null $dayOfWeek day of the week default null
308
     *
309
     * @return static
310
     */
311
    public function lastOfYear($dayOfWeek = null)
312
    {
313
        return $this->month(static::MONTHS_PER_YEAR)->lastOfMonth($dayOfWeek);
314
    }
315
 
316
    /**
317
     * Modify to the given occurrence of a given day of the week
318
     * in the current year. If the calculated occurrence is outside the scope
319
     * of the current year, then return false and no modifications are made.
320
     * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
321
     *
322
     * @param int $nth
323
     * @param int $dayOfWeek
324
     *
325
     * @return mixed
326
     */
327
    public function nthOfYear($nth, $dayOfWeek)
328
    {
329
        $date = $this->avoidMutation()->firstOfYear()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
330
 
331
        return $this->year === $date->year ? $this->modify((string) $date) : false;
332
    }
333
 
334
    /**
335
     * Modify the current instance to the average of a given instance (default now) and the current instance
336
     * (second-precision).
337
     *
338
     * @param \Carbon\Carbon|\DateTimeInterface|null $date
339
     *
340
     * @return static
341
     */
342
    public function average($date = null)
343
    {
344
        return $this->addRealMicroseconds((int) ($this->diffInRealMicroseconds($this->resolveCarbon($date), false) / 2));
345
    }
346
 
347
    /**
348
     * Get the closest date from the instance (second-precision).
349
     *
350
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date1
351
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date2
352
     *
353
     * @return static
354
     */
355
    public function closest($date1, $date2)
356
    {
357
        return $this->diffInRealMicroseconds($date1) < $this->diffInRealMicroseconds($date2) ? $date1 : $date2;
358
    }
359
 
360
    /**
361
     * Get the farthest date from the instance (second-precision).
362
     *
363
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date1
364
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date2
365
     *
366
     * @return static
367
     */
368
    public function farthest($date1, $date2)
369
    {
370
        return $this->diffInRealMicroseconds($date1) > $this->diffInRealMicroseconds($date2) ? $date1 : $date2;
371
    }
372
 
373
    /**
374
     * Get the minimum instance between a given instance (default now) and the current instance.
375
     *
376
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
377
     *
378
     * @return static
379
     */
380
    public function min($date = null)
381
    {
382
        $date = $this->resolveCarbon($date);
383
 
384
        return $this->lt($date) ? $this : $date;
385
    }
386
 
387
    /**
388
     * Get the minimum instance between a given instance (default now) and the current instance.
389
     *
390
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
391
     *
392
     * @see min()
393
     *
394
     * @return static
395
     */
396
    public function minimum($date = null)
397
    {
398
        return $this->min($date);
399
    }
400
 
401
    /**
402
     * Get the maximum instance between a given instance (default now) and the current instance.
403
     *
404
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
405
     *
406
     * @return static
407
     */
408
    public function max($date = null)
409
    {
410
        $date = $this->resolveCarbon($date);
411
 
412
        return $this->gt($date) ? $this : $date;
413
    }
414
 
415
    /**
416
     * Get the maximum instance between a given instance (default now) and the current instance.
417
     *
418
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
419
     *
420
     * @see max()
421
     *
422
     * @return static
423
     */
424
    public function maximum($date = null)
425
    {
426
        return $this->max($date);
427
    }
428
 
429
    /**
430
     * Calls \DateTime::modify if mutable or \DateTimeImmutable::modify else.
431
     *
432
     * @see https://php.net/manual/en/datetime.modify.php
433
     *
434
     * @return static|false
435
     */
436
    #[ReturnTypeWillChange]
437
    public function modify($modify)
438
    {
439
        return parent::modify((string) $modify);
440
    }
441
 
442
    /**
443
     * Similar to native modify() method of DateTime but can handle more grammars.
444
     *
445
     * @example
446
     * ```
447
     * echo Carbon::now()->change('next 2pm');
448
     * ```
449
     *
450
     * @link https://php.net/manual/en/datetime.modify.php
451
     *
452
     * @param string $modifier
453
     *
454
     * @return static|false
455
     */
456
    public function change($modifier)
457
    {
458
        return $this->modify(preg_replace_callback('/^(next|previous|last)\s+(\d{1,2}(h|am|pm|:\d{1,2}(:\d{1,2})?))$/i', function ($match) {
459
            $match[2] = str_replace('h', ':00', $match[2]);
460
            $test = $this->avoidMutation()->modify($match[2]);
461
            $method = $match[1] === 'next' ? 'lt' : 'gt';
462
            $match[1] = $test->$method($this) ? $match[1].' day' : 'today';
463
 
464
            return $match[1].' '.$match[2];
465
        }, strtr(trim($modifier), [
466
            ' at ' => ' ',
467
            'just now' => 'now',
468
            'after tomorrow' => 'tomorrow +1 day',
469
            'before yesterday' => 'yesterday -1 day',
470
        ])));
471
    }
472
}