blob: 4cd66b676f1df2cdeeeae9611420575d76ab0302 [file] [log] [blame]
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +02001<?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 */
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010011
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020012namespace Carbon\Traits;
13
14use Carbon\CarbonInterval;
15use Carbon\Exceptions\InvalidIntervalException;
16use DateInterval;
17
18/**
19 * Trait to call rounding methods to interval or the interval of a period.
20 */
21trait IntervalRounding
22{
23 protected function callRoundMethod(string $method, array $parameters)
24 {
25 $action = substr($method, 0, 4);
26
27 if ($action !== 'ceil') {
28 $action = substr($method, 0, 5);
29 }
30
31 if (\in_array($action, ['round', 'floor', 'ceil'])) {
32 return $this->{$action.'Unit'}(substr($method, \strlen($action)), ...$parameters);
33 }
34
35 return null;
36 }
37
38 protected function roundWith($precision, $function)
39 {
40 $unit = 'second';
41
42 if ($precision instanceof DateInterval) {
43 $precision = (string) CarbonInterval::instance($precision);
44 }
45
46 if (\is_string($precision) && preg_match('/^\s*(?<precision>\d+)?\s*(?<unit>\w+)(?<other>\W.*)?$/', $precision, $match)) {
47 if (trim($match['other'] ?? '') !== '') {
48 throw new InvalidIntervalException('Rounding is only possible with single unit intervals.');
49 }
50
51 $precision = (int) ($match['precision'] ?: 1);
52 $unit = $match['unit'];
53 }
54
55 return $this->roundUnit($unit, $precision, $function);
56 }
57}