Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Romain's avatar
Level 30

Carbon returning same date with add and sub weeks

Hi there,

I've got a "simple" issue here. Im trying to have Carbon give me a range of dates based on now. For a start date I want to remove some weeks, and for an end date I want to add some weeks from now. However with what I wrote below, I get the same date for both start and end.

Any idea why?

Thanks

$date = Carbon::now();
$start = $date->subWeeks(rand(1, 52));
$end = $date->addWeeks(rand(1, 52));

logger($start . ' == ' . $end);
// Logs: local.DEBUG: 2021-07-08 07:57:23 == 2021-07-08 07:57:23
// not only that but I also get dates in the future even for start: 2022-07-14 07:57:23 == 2022-07-14 07:57:23
0 likes
9 replies
MichalOravec's avatar
$date = Carbon::now();
$start = $date->copy()->subWeeks(rand(1, 52));
$end = $date->copy()->addWeeks(rand(1, 52));

or

$date = CarbonImmutable::now();
$start = $date->subWeeks(rand(1, 52));
$end = $date->addWeeks(rand(1, 52));
1 like
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

You are mutating the date.. Carbon overwrites the date on the object. You need to clone it

$date = Carbon::now();
$start = $date->clone()->subWeeks(rand(1, 52));
$end = $date->clone()->addWeeks(rand(1, 52));

//or create a new instance for each
$start = Carbon::now()->subWeeks(rand(1, 52));
$end = Carbon::now()->addWeeks(rand(1, 52));

// or cast to immutable
$date = Carbon::now()->toImmutable();
$start = $date->subWeeks(rand(1, 52));
$end = $date->addWeeks(rand(1, 52));

edit: ->clone() and ->copy() are just aliases of each other. They do the same thing

Romain's avatar
Level 30

@Sinnbeck Thanks, I ended up going with the simple new instances solution: Carbon::now()->addWeeks(rand(1, 52))

It's still a bit strange. I would have expected that $start keeps its value intact after declaration. The fact that there's a change somewhere down the line and the value gets re-assigned is a bit off.

Thanks for your help.

Snapey's avatar

@Romain you misunderstand the problem

$date = Carbon::now();
$start = $date->subWeeks(rand(1, 52));
$end = $date->addWeeks(rand(1, 52));

$start is a live copy of $date not an independent object (its a reference to the original $date)

Then you are manipulation $date by adding and subtracting weeks, so $start and $end will change

There is a second problem in that when you sub weeks $date is modified so when you add weeks you are adding to the new value of $date not the original

Your original problem would have been simply solved as

$start = now()->subWeeks(rand(1, 52));
$end = now()->addWeeks(rand(1, 52));

since the now() helper returns a new instance each time

1 like
MichalOravec's avatar

@Snapey I was searching for this method now. The documentation of carbon is so bad. Because I know that it exists but I forgot the name of the class.

1 like
Sinnbeck's avatar

You can also cast it after creating it

$date = Carbon::now()->toImmutable();
$start = $date->subWeeks(rand(1, 52));
$end = $date->addWeeks(rand(1, 52));
1 like
Snapey's avatar

latest versions you can also cast it in the model

Please or to participate in this conversation.