Human readable Intervals
Every Laravel application has several configuration values that represent a given amount of seconds or minutes.
queue.connections.*.retry_after and a lot more.
By default all these values are a single integer like
10800, some of them even missing the unit in the description.
I bet that most of you know and have already done the easiest way - replace the single integer with a multiplication like
3 * 60 * 60 which is the same as
Another benefit is that you can guess what's the interval as it's
days * minutes * seconds.
But there are still problems:
- it requires brain capacity to parse the multiplication
- not all intervals are seconds - how would you differentiate between
10 * 60(10 hours in minutes) and
10 * 60(10 minutes in seconds)
- it gets even harder when you need an interval like "2 days 6 hours" in seconds
(2 * 24 * 60 * 60) + (6 * 60 * 60)
Luckily there's a solution for both issues.
This class comes with a human-readable fluent API to write your interval however you want.
The important part is the magic property
totalSeconds - similar properties exist for minutes, days and so on.
use Carbon\CarbonInterval; CarbonInterval::days(2)->hours(6)->totalSeconds;
This is helpful in every part of your application - not only the configuration but also the real app code, for example cache TTL, signed URL expiration and wherever you need a given amount of seconds, minutes or other time units.
@devfrey asked how this works with constants.
Short: it doesn't.
I would recommend using the multiplication or single integer solution with an explanatory comment. I'm always using two comments - one above the
const which describes the value and one at the end of the line that contains the unit.
// 5 minutes const DEFAULT_TTL = 5 * 60; // seconds // 7 days const REMINDER_DELAY = 7 * 24 * 60; // minutes
In some cases you possibly want to use a
.env variable to define your config interval and it should be possible to change the insert units - for example for development/testing purposes.
So by default it's
7 days but you want to be able to set it to
5 minutes without adjusting your code or complex conditions.
The solution is the static
\Carbon\CarbonInterval::fromString() method that accepts a string, similar but different to
In one of our projects we had to prevent password reset for 7 days after it was successfully reset. But for sure we had to use something like 5-10 minutes on our local machines and several hours on our staging system.
use Carbon\CarbonInterval; return [ // ... 'password_reset_decay' => CarbonInterval::fromString(env('PASSWORD_RESET_DECAY', '7 days'))->totalSeconds, // ... ];
And in your
.env file you can define the values like the following.
# production PASSWORD_RESET_DECAY="7 days" # staging PASSWORD_RESET_DECAY="1 day" # development PASSWORD_RESET_DECAY="6 hours" # local PASSWORD_RESET_DECAY="10 minutes"