Skip to content

Commit

Permalink
Merge pull request #2347 from briannesbitt/feature/add-real-units-dec…
Browse files Browse the repository at this point in the history
…imal

Support decimal numbers in addRealUnit
  • Loading branch information
kylekatarnls committed Jun 1, 2021
2 parents 0833b01 + 05af371 commit 1766a7e
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 28 deletions.
37 changes: 28 additions & 9 deletions src/Carbon/CarbonInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -763,18 +763,18 @@ public function __toString();
*
* @return static
*/
public function add($unit, $value = 1, $overflow = null);
public function add($unit, $value = 1, bool $overflow = null);

/**
* Add seconds to the instance using timestamp. Positive $value travels
* forward while negative $value travels into the past.
*
* @param string $unit
* @param int $value
* @param string $unit
* @param int|float $value
*
* @return static
*/
public function addRealUnit($unit, $value = 1);
public function addRealUnit(string $unit, $value = 1);

/**
* Add given units to the current instance.
Expand All @@ -785,7 +785,7 @@ public function addRealUnit($unit, $value = 1);
*
* @return static
*/
public function addUnit($unit, $value = 1, $overflow = null);
public function addUnit(string $unit, int $value = 1, bool $overflow = null);

/**
* Add any unit to a new value without overflowing current other unit given.
Expand Down Expand Up @@ -1234,6 +1234,25 @@ public static function createMidnightDate($year = null, $month = null, $day = nu
*/
public static function createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null);

/**
* Create a new Carbon instance from a specific date and time using strict validation.
*
* @see create()
*
* @param int|null $year
* @param int|null $month
* @param int|null $day
* @param int|null $hour
* @param int|null $minute
* @param int|null $second
* @param DateTimeZone|string|null $tz
*
* @throws InvalidFormatException
*
* @return static
*/
public static function createStrict(int $year = 0, int $month = 1, int $day = 1, int $hour = 0, int $minute = 0, int $second = 0, $tz = null);

/**
* Get/set the day of year.
*
Expand Down Expand Up @@ -2592,7 +2611,7 @@ public function isMidnight(): bool;
*
* @return bool
*/
public static function isModifiableUnit($unit);
public static function isModifiableUnit($unit): bool;

/**
* Returns true if the current class/instance is mutable.
Expand Down Expand Up @@ -4007,7 +4026,7 @@ public function startOfYear();
*
* @return static
*/
public function sub($unit, $value = 1, $overflow = null);
public function sub($unit, $value = 1, bool $overflow = null);

/**
* Subtract seconds to the instance using timestamp. Positive $value travels
Expand All @@ -4029,7 +4048,7 @@ public function subRealUnit($unit, $value = 1);
*
* @return static
*/
public function subUnit($unit, $value = 1, $overflow = null);
public function subUnit(string $unit, int $value = 1, bool $overflow = null);

/**
* Subtract any unit to a new value without overflowing current other unit given.
Expand All @@ -4053,7 +4072,7 @@ public function subUnitNoOverflow($valueUnit, $value, $overflowUnit);
*
* @return static
*/
public function subtract($unit, $value = 1, $overflow = null);
public function subtract($unit, $value = 1, bool $overflow = null);

/**
* Get the difference in a human readable format in the current locale from current instance to an other
Expand Down
1 change: 1 addition & 0 deletions src/Carbon/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
* will be 0.
* If one of the set values is not valid, an InvalidDateException
* will be thrown.
* @method Carbon createStrict(int $year = 0, int $month = 1, int $day = 1, int $hour = 0, int $minute = 0, int $second = 0, $tz = null) Create a new Carbon instance from a specific date and time using strict validation.
* @method Carbon disableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
* You should rather use the ->settings() method.
* @method Carbon enableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
Expand Down
1 change: 1 addition & 0 deletions src/Carbon/FactoryImmutable.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
* will be 0.
* If one of the set values is not valid, an InvalidDateException
* will be thrown.
* @method CarbonImmutable createStrict(int $year = 0, int $month = 1, int $day = 1, int $hour = 0, int $minute = 0, int $second = 0, $tz = null) Create a new Carbon instance from a specific date and time using strict validation.
* @method CarbonImmutable disableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
* You should rather use the ->settings() method.
* @method CarbonImmutable enableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
Expand Down
41 changes: 22 additions & 19 deletions src/Carbon/Traits/Units.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ trait Units
* Add seconds to the instance using timestamp. Positive $value travels
* forward while negative $value travels into the past.
*
* @param string $unit
* @param int $value
* @param string $unit
* @param int|float $value
*
* @return static
*/
public function addRealUnit($unit, $value = 1)
public function addRealUnit(string $unit, $value = 1): self
{
switch ($unit) {
// @call addRealUnit
Expand Down Expand Up @@ -131,8 +131,13 @@ public function addRealUnit($unit, $value = 1)
return $this;
}

/* @var CarbonInterface $this */
return $this->setTimestamp((int) ($this->getTimestamp() + $value));
$seconds = (int) $value;
$microseconds = (int) round(
(abs($value) - abs($seconds)) * ($value < 0 ? -1 : 1) * static::MICROSECONDS_PER_SECOND,
);
$date = $this->setTimestamp($this->getTimestamp() + $seconds);

return $microseconds ? $date->addRealUnit('microsecond', $microseconds) : $date;
}

/**
Expand All @@ -144,7 +149,7 @@ public function addRealUnit($unit, $value = 1)
*
* @return static
*/
public function subRealUnit($unit, $value = 1)
public function subRealUnit($unit, $value = 1): self
{
return $this->addRealUnit($unit, -$value);
}
Expand All @@ -156,7 +161,7 @@ public function subRealUnit($unit, $value = 1)
*
* @return bool
*/
public static function isModifiableUnit($unit)
public static function isModifiableUnit($unit): bool
{
static $modifiableUnits = [
// @call addUnit
Expand All @@ -183,7 +188,7 @@ public static function isModifiableUnit($unit)
*
* @return static
*/
public function rawAdd(DateInterval $interval)
public function rawAdd(DateInterval $interval): self
{
return parent::add($interval);
}
Expand All @@ -202,7 +207,7 @@ public function rawAdd(DateInterval $interval)
* @return static
*/
#[ReturnTypeWillChange]
public function add($unit, $value = 1, $overflow = null)
public function add($unit, $value = 1, ?bool $overflow = null): self
{
if (\is_string($unit) && \func_num_args() === 1) {
$unit = CarbonInterval::make($unit);
Expand All @@ -224,7 +229,7 @@ public function add($unit, $value = 1, $overflow = null)
[$value, $unit] = [$unit, $value];
}

return $this->addUnit($unit, $value, $overflow);
return $this->addUnit((string) $unit, (int) $value, $overflow);
}

/**
Expand All @@ -236,11 +241,11 @@ public function add($unit, $value = 1, $overflow = null)
*
* @return static
*/
public function addUnit($unit, $value = 1, $overflow = null)
public function addUnit(string $unit, int $value = 1, ?bool $overflow = null): self
{
$date = $this;

if (!is_numeric($value) || !\floatval($value)) {
if ($value === 0) {
return $date->isMutable() ? $date : $date->copy();
}

Expand Down Expand Up @@ -290,8 +295,6 @@ public function addUnit($unit, $value = 1, $overflow = null)
$day = $date->day;
}

$value = (int) $value;

if ($unit === 'milli' || $unit === 'millisecond') {
$unit = 'microsecond';
$value *= static::MICROSECONDS_PER_MILLISECOND;
Expand Down Expand Up @@ -319,7 +322,7 @@ public function addUnit($unit, $value = 1, $overflow = null)
*
* @return static
*/
public function subUnit($unit, $value = 1, $overflow = null)
public function subUnit(string $unit, int $value = 1, ?bool $overflow = null): self
{
return $this->addUnit($unit, -$value, $overflow);
}
Expand All @@ -331,7 +334,7 @@ public function subUnit($unit, $value = 1, $overflow = null)
*
* @return static
*/
public function rawSub(DateInterval $interval)
public function rawSub(DateInterval $interval): self
{
return parent::sub($interval);
}
Expand All @@ -350,7 +353,7 @@ public function rawSub(DateInterval $interval)
* @return static
*/
#[ReturnTypeWillChange]
public function sub($unit, $value = 1, $overflow = null)
public function sub($unit, $value = 1, ?bool $overflow = null): self
{
if (\is_string($unit) && \func_num_args() === 1) {
$unit = CarbonInterval::make($unit);
Expand All @@ -372,7 +375,7 @@ public function sub($unit, $value = 1, $overflow = null)
[$value, $unit] = [$unit, $value];
}

return $this->addUnit($unit, -\floatval($value), $overflow);
return $this->addUnit((string) $unit, -((int) $value), $overflow);
}

/**
Expand All @@ -386,7 +389,7 @@ public function sub($unit, $value = 1, $overflow = null)
*
* @return static
*/
public function subtract($unit, $value = 1, $overflow = null)
public function subtract($unit, $value = 1, ?bool $overflow = null): self
{
if (\is_string($unit) && \func_num_args() === 1) {
$unit = CarbonInterval::make($unit);
Expand Down

0 comments on commit 1766a7e

Please sign in to comment.