-
-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Carbon setters order matters and returns wrong date #1
Comments
Best practice if you have a full date is to use 1 method to make 1 mutation instead of 3 successive mutations which is a waste of resources anyway: $startAt = Carbon::parse('2022-06-29 08:00:00.0');
echo $startAt->modify('2022-08-31'); // Tell exactly what you expect and get it
// If you have integers:
$startAt = Carbon::parse('2022-06-29 08:00:00.0');
echo $startAt->setDate(2022, 8, 31); Those are actually native methods from PHP While $startAt = new DateTime('2022-06-29 08:00:00.0');
$startAt->setDate($startAt->format('Y'), $startAt->format('n'), 31); // Impossible date => overflow to 2022-07-01
$startAt->setDate($startAt->format('Y'), 8, $startAt->format('j'));
$startAt->setDate(2022, $startAt->format('n'), $startAt->format('j')); |
This is awesome and makes totally sense. Thank you very much! |
I’d like to raise the question of whether we should consider re-opening this. Carbon::setTestNow('2024-12-31'); // Let's pretend, today is December 31st
$date = Carbon::now()->year(2024)->month(4)->day(1); // Instantiate a new date object
var_dump($date->format('Y-m-d')); // Expected: 2024/04/01 --- Actual: 2024/05/01 While the actual output makes sense if you know what’s happening behind the scenes, it’s highly unintuitive at first glance. I’m not sure how to address this, but I think it’s worth discussing. Backward compatibility might be an important concern, but in my opinion, something needs to be changed here. One possible solution could be to throw an exception if year or month is set to a value that results in an invalid date for the current instance. For example, if the current date’s month has 31 days and you set it to a month with fewer than 31 days, instead of silently adjusting the date's day to the next month, an exception could be thrown to clearly indicate the issue. The same issue arises not only for changing the month, but the year - because of leap years. What are your thoughts? |
Hello, Carbon is not a builder, so every time you call And so, it's less than ideal to use those methods to actually build a date. I.E. don't do: $date->year(2024)->month(4)->day(1); Do: $date->setDate(2024, 4, 1); So it's only 1 mutation and no overflow problem. BTW, if you don't need the current time, then you don't need to start from Many overflow problems that got reported here and there often have this sub-optimal patterns (i.e. start from now or an arbitrary date while actually not using anything from it, or doing in multiple steps an operation that can be done in one go). About throwing an exception when overflowing, it cannot happen on 3.x, but that's definitely an option on the table for 4.x. The main problem about it is the discoverability issue. I.E. I build my code, it works, I ship it, but then errors happens only on some days or in some combos of operations, and so possibly don't get noticed before they hit many real users. (depending how logging is done, it might even goes under radar). |
Hello,
I encountered an issue with the following code:
Carbon version: 2.61.0
PHP version: 8.1
I expected to get:
But I actually get:
I guess that belongs to mutations of days through months the day like 31 does not exist and the date jumps to the next possible day. Is there a
best practice-way
to make sure this never happens? So this might not be a "bug" but i want to make sure to get my target dates and sleep well 😅.Thanks!
The text was updated successfully, but these errors were encountered: