Silly question. But I cant get the result I want.
I have a Interval field which is calculated (for a single record) in JS which can house values of '32:00:00'
But now I need to subtract eg. '04:00:00' from that, but its done in PHP in the back end.
But it seems to stop at '23:59:59'. I know its because its a full day.
Is there a way to calculate the interval to show something like '32:00:00'
$readyDate = substr($pat['ready4disch_date'],0,10);
$readyTime = ($pat['ready4disch_time'] != null) ? $pat['ready4disch_time'] : '00:00:00';
$disDate = substr($pat['date_unit_discharge'],0,10);
$disTime = ($pat['time_unit_discharge'] != null) ? $pat['time_unit_discharge'] : '00:00:00';
$ready = new Carbon($readyDate.' '.$readyTime);
$discharge = new Carbon($disDate.' '.$disTime);
//Calculate difference between decision and admission
$min = $ready->diff($discharge);
$admSec = date_create('@0')->add($min)->getTimestamp();
//Convert Margin to usable time
$marSec = strtotime($margin) - strtotime('TODAY'); // 3600
//Subtract margin from delay
$result = $admSec - $marSec;
$result = ($result > 0 ) ? $this->secondsToTime($result) : $this->secondsToTime(0);
CodePudding user response:
The trouble is that you're trying to trick a date library into doing basic interval math, and it doesn't like trying to interpret times later than 23:59:59
because it will either consider them impossible, or edge case misrepresentations of data reinterpreted to "the next day".
Rather than trying to force this fish to ride a bicycle I'd say it's more productive to whip up something that does the relatively simple thing that you actually want to do.
class SimpleInterval {
protected $seconds;
protected static $conv = [1, 60, 60];
public function __construct(int $seconds) {
$this->seconds = $seconds;
}
public static function fromString(string $interval) {
$seconds = 0;
$mul = 1;
$parts = array_reverse(explode(":", $interval));
$c=count($parts);
if( $c > count(self::$conv) ) {
throw new \Exception('Supplied interval string has more components than I know how to convert.');
}
for( $i=0; $i<$c; $i ) {
$mul *= self::$conv[$i];
$seconds = $parts[$i] * $mul;
}
return new self($seconds);
}
public function getSeconds() {
return $this->seconds;
}
public function subtract(SimpleInterval $i) {
return new self($this->seconds - $i->getSeconds());
}
public function __toString() {
$res=[];
$time = $this->seconds;
$mul = 1;
for( $i=1, $c=count(self::$conv); $i<$c; $i ) {
$mul = self::$conv[$i];
$cur = $time % $mul;
$res[] = $cur;
$time = ($time - $cur) / $mul;
}
$res[] = $time;
return implode(':', array_map(
function($a){return sprintf('d', $a);},
array_reverse($res)
));
}
public function asDateInterval() {
return new DateInterval(sprintf('PT%dS', $this->seconds));
}
}
$a = '32:00:00';
$b = '4:00:00';
var_dump(
$c = SimpleInterval::fromString($a)->subtract(SimpleInterval::fromString($b)),
(string)$c,
$c->asDateInterval()
);
Output:
object(SimpleInterval)#3 (1) {
["seconds":protected]=>
int(100800)
}
string(8) "28:00:00"
object(DateInterval)#1 (16) {
["y"]=>
int(0)
["m"]=>
int(0)
["d"]=>
int(0)
["h"]=>
int(0)
["i"]=>
int(0)
["s"]=>
int(100800)
["f"]=>
float(0)
["weekday"]=>
int(0)
["weekday_behavior"]=>
int(0)
["first_last_day_of"]=>
int(0)
["invert"]=>
int(0)
["days"]=>
bool(false)
["special_type"]=>
int(0)
["special_amount"]=>
int(0)
["have_weekday_relative"]=>
int(0)
["have_special_relative"]=>
int(0)
}