briannesbitt / Carbon

A simple PHP API extension for DateTime.
https://carbon.nesbot.com/
MIT License
16.58k stars 1.28k forks source link

Cant create negative interval between 00:00 and -01:00 #3059

Closed alves-raphael closed 4 months ago

alves-raphael commented 4 months ago

Hello,

I encountered an issue with the following code:

CarbonInterval::createFromFormat('H:i', '-00:59');

Carbon version: 3.4.0

PHP version: 8.3.7

I expected to get:

Carbon\CarbonInterval {
    interval: - 00:59:00.0,
  }

But I actually get:

Carbon\CarbonInterval {
    interval: + 00:59:00.0,
  }

As stated in the print below, it seems like it's impossible to create a negative interval between 00:00 and -01:00, using the "H:i" format. image Let me now if I can do anything to contribute to solve this or any other issue! Thanks!

kylekatarnls commented 4 months ago

Hello, the negative sign is per unit:

var_dump(CarbonInterval::createFromFormat('H:i', '-00:59')); // -0 hours +59 minutes
var_dump(CarbonInterval::createFromFormat('H:i', '00:-59')); // +0 hours -59 minutes
var_dump(CarbonInterval::createFromFormat('H:i', '-01:59')); // -1 hour +59 minutes
var_dump(CarbonInterval::createFromFormat('H:i', '01:-59')); // +1 hour -59 minutes

Note that the interval is positive in any case above and it would be even with '-01:-59' (only the units are negative).

If your string can start with a - but not contain it anywhere else, then you can do this to have an interval with all units positive but the whole interval negative (inverted):

$duration = '-00:59';
$negative = str_starts_with($duration, '-');

if ($negative) {
  $duration = substr($duration, 1);
}

$interval = CarbonInterval::createFromFormat($duration);

if ($negative) {
  $interval = $interval->invert();
}

How does this solution sound to to you?

alves-raphael commented 4 months ago

That looks like it could handle the job. Thank you!