briannesbitt / Carbon

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

How to get custom string of interval at @forHumans? #2231

Closed KiddoLin closed 3 years ago

KiddoLin commented 3 years ago

Hello,

I encountered an issue with the following code:

echo Carbon\CarbonInterval::days(7)->forHumans();
echo Carbon\CarbonInterval::days(1)->forHumans();

Carbon version: 2.27.0

PHP version: 7.4.9

I expected to get:

7天
24小时

But I actually get:

1周
1天

Thanks!

kylekatarnls commented 3 years ago

Hello,

This is the expected behavior (and majority of users likely rely on this behavior), interval are kept as you compose them. To get 24小时, you need:

echo Carbon\CarbonInterval::hours(24)->forHumans();

Thanks.

kylekatarnls commented 3 years ago

The week is a particular unit as it cannot not be stored in DateInterval, let me check the doc. There is a way to skip it if I recall correctly.

KiddoLin commented 3 years ago

@kylekatarnls Thanks for your 'reopened'.I have to use Carbon\CarbonInterval::days() becase i only get the num of days from others, then the message is requested to show to customers with 'day' if the num over 1 day or show 'hour' if the num less than 1day.

KiddoLin commented 3 years ago

By the way, the '1 week' is maybe means 7 days or 5 workdays, that is why the message is requested to show with 'day' rather than 'week'.

kylekatarnls commented 3 years ago

A week is by the definition of the dictionary "a period of seven successive days". This widely used definition will remain the default behavior for forHumans().

Any other consideration such as 5 workdays is a business concern (some businesses have more or less than 5 working days), so use setCascadeFactors as detailed in the documentation to customize the cascading:

CarbonInterval::setCascadeFactors([
    // other factors...
    'week' => [5, 'days'],
    // other factors...
]);

echo CarbonInterval::days(7)->forHumans(); // 1 week 2 days

And to disable the days to week cascade, use a very big number so it never caps:

CarbonInterval::setCascadeFactors([
    'week' => [999999999, 'days'],
]);

echo CarbonInterval::days(7)->forHumans(); // 7 days
// In this mode, every unit will appears as it's set in the interval
echo CarbonInterval::weeks(1)->add(28, 'hours')->forHumans(); // 7 days 28 hours

Thanks.