How to add CarbonInterval instance in Carbon instance
Asked Answered
S

2

8

I have a carbon instance

   $a = Carbon\Carbon::now();

   Carbon\Carbon {
     "date": "2018-06-11 10:00:00",
     "timezone_type": 3,
     "timezone": "Europe/Vienna",
   }

and a CarbonInterval instance

   $b = CarbonInterval::make('1month');


     Carbon\CarbonInterval {
     "y": 0,
     "m": 1,
     "d": 0,
     "h": 0,
     "i": 0,
     "s": 0,
     "f": 0.0,
     "weekday": 0,
     "weekday_behavior": 0,
     "first_last_day_of": 0,
     "invert": 0,
     "days": false,
     "special_type": 0,
     "special_amount": 0,
     "have_weekday_relative": 0,
     "have_special_relative": 0,
   }

How to add the interval in the carbon instance so that I would get

   Carbon\Carbon {
     "date": "2018-07-11 10:00:00",
     "timezone_type": 3,
     "timezone": "Europe/Vienna",
   }

I am aware of solution that involve converting it to timestamp or Datetime class like this

strtotime( date('Y-m-d H:i:s', strtotime("+1 month", $a->timestamp ) ) );  

which is what currently I am using but I am looking for a more "carbony" way I searched through the official site but couldn't find anything on this so need some help.

Update: Just to give you the context On frontend I have two controls 1st is for interval (days,months,year) 2nd is a text box so depending on the combination I generate strings dynamically like "2 days" , "3 months" so on that then gets feed to interval classes

Skullcap answered 11/6, 2018 at 15:24 Comment(0)
V
15

I'm not aware of a built-in function to add an interval, but what should work is adding the total seconds of an interval to the date:

$date = Carbon::now(); // 2018-06-11 17:54:34
$interval = CarbonInterval::make('1hour');

$laterThisDay = $date->addSeconds($interval->totalSeconds); // 2018-06-11 18:54:34

Edit: Found an easier way!

$date = Carbon::now(); // 2018-06-11 17:54:34
$interval = CarbonInterval::make('1hour');

$laterThisDay = $date->add($interval); // 2018-06-11 18:54:34

This works because Carbon is based on DateTime and CarbonInterval is based on DateInterval. See here for method reference.

Vaporing answered 11/6, 2018 at 15:55 Comment(0)
C
2

See documentation https://carbon.nesbot.com/docs/#api-addsub

$carbon = Carbon\Carbon::now();
$monthLater = clone $carbon;
$monthLater->addMonth(1);
dd($carbon, $monthLater);

result is

Carbon {#416 ▼
  +"date": "2018-06-11 16:00:48.127648"
  +"timezone_type": 3
  +"timezone": "UTC"
}

Carbon {#418 ▼
  +"date": "2018-07-11 16:00:48.127648"
  +"timezone_type": 3
  +"timezone": "UTC"
}

For this interval [months, centuries, years, quarters, days, weekdays, weeks, hours, minutes, seconds], type you can use

$count = 1; // for example
$intrvalType = 'months'; // for example
$addInterval = 'add' . ucfirst($intrvalType);
$subInterval = 'sub' . ucfirst($intrvalType);
$carbon = Carbon\Carbon::now();
dd($carbon->{$addInterval}($count));
dd($carbon->{$subInterval}($count));
Compost answered 11/6, 2018 at 15:48 Comment(6)
Thanx but I am generating the interval dynamically. If I go by this I would need a lot of if else for every case (days, month etc) which is what I am trying to avoid in the first place.Skullcap
Can you your dynamic part of code convert to string??Compost
If you can you can use this code $carbon->addSeconds(1);Compost
CarbonInterval::make('{$count}{$interval}'); here these two variables come from user, depending on which it generates appropriate interval like for example strings like $count=2 and $interval = 'days' gives 2days; or another example $count=3 and $interval = 'months' gives "3months" which you then feed to CarbonInterval to get interval of 3 monthsSkullcap
@Viney see my updated answer how you can do using my suggested methodCompost
Yea this is nice alternative solution.Skullcap

© 2022 - 2024 — McMap. All rights reserved.