August 23, 2024 • 6 min read
Laravel makes timestamp handling easy, but there's a right way and a wrong way. In this guide, you'll learn how Laravel's built-in timestamp handling works with UTC, how to use Carbon for timezone conversion, and how to display timestamps correctly in JS-based frontends.
A common belief is that Laravel always stores timestamps in UTC, but that’s not actually the case. Laravel stores timestamps using whatever timezone you set in config/app.php. So if your app timezone is set to America/New_York, then created_at and updated_at will be stored in Eastern Time unless you manually standardize them.
What Laravel does guarantee is that the timestamps are always returned as Carbon instances in your application timezone. That’s why it can feel like everything is using UTC behind the scenes, but the storage layer depends on how your app is configured.
Even though Laravel doesn’t enforce UTC, storing timestamps in UTC is still the best practice. UTC avoids issues with daylight savings transitions and makes integrations with services like Stripe, Twilio, and AWS more predictable. To follow this convention, you only need to set your app timezone or your database connection to UTC and your timestamps will be stored consistently.
Laravel doesn't assume your database timestamps are stored in UTC. Instead, it reads the raw timestamp from the database and wraps it in a Carbon instance using the timezone defined in config/app.php. This means the timezone of the Carbon instance depends on your application configuration.
// config/app.php
'timezone' => 'America/New_York';
$post = Post::find(1);
echo $post->created_at->timezone; // "America/New_York"
If your application timezone is set to UTC, then Carbon will display UTC. If it’s set to a different region, Carbon will use that instead.
This behavior keeps things consistent inside your application. As long as you know what timezone your app is configured to use, Carbon makes conversions clear and predictable across your codebase.
Storing timestamps in UTC aligns perfectly with Laravel's ecosystem and third-party packages:
When you choose to store timestamps in UTC in your Laravel application, you avoid conversion issues when integrating with these services. Your entire stack speaks the same time language, reducing the chances of miscommunication between systems.
Let's talk about some of the different strategies we have when having to do time converstions.
The simplest approach is to send the UTC timestamp to the frontend and use JavaScript to convert it to the user’s local time.
In JavaScript, you can easily achieve this using Date objects or a library like moment.js or day.js.
// Assuming you have a UTC timestamp from the backend
let utcTimestamp = "2024-08-23T12:00:00Z";
// Convert to the user's local timezone using JavaScript
let localDate = new Date(utcTimestamp);
console.log(localDate.toLocaleString());
This approach has several advantages:
However, this method might not always be ideal for server-side rendering scenarios or when handling bulk data processing.
Another approach is to handle the conversion on the server side based on the user’s timezone, which can be stored in the database.
For example, in Laravel, you could convert the timestamp to the user's timezone before sending it to the frontend.
use Carbon\Carbon;
// Assuming you have a UTC timestamp and the user's timezone
$utcTimestamp = '2024-08-23 12:00:00';
$userTimezone = 'America/New_York';
$convertedTimestamp = Carbon::createFromFormat('Y-m-d H:i:s', $utcTimestamp, 'UTC')
->setTimezone($userTimezone);
echo $convertedTimestamp; // Displays the timestamp in the user's local timezone
In this method, the server sends the converted timestamp directly to the client, ensuring consistency across platforms. It’s useful when you need to perform server-side operations based on user-specific times, such as generating reports or scheduling tasks.
One way to combine the benefits of both client-side and server-side rendering is to store the user’s timezone in the database when they register or log in.
// Example of storing the user's timezone in the database during registration
$user->timezone = $request->input('timezone');
$user->save();
// Later, when rendering timestamps
$timestampInUserTimezone = Carbon::createFromFormat('Y-m-d H:i:s', $utcTimestamp, 'UTC')
->setTimezone($user->timezone);
This hybrid approach gives you flexibility in handling different scenarios, whether you need to generate reports server-side or provide a dynamic UI that updates based on local times.
One tricky aspect of dealing with timezones is Daylight Savings Time (DST). When handling user timezones that observe DST, you need to ensure that your conversions account for these shifts.
Fortunately, libraries like Carbon in Laravel and moment.js or day.js on the frontend handle DST changes automatically, as long as you use the correct timezone identifier (e.g., America/New_York instead of just EST).
Storing timestamps in UTC is the best practice for maintaining consistency, especially when dealing with applications that serve a global audience. Once the timestamps are securely stored in UTC, you have several options for rendering them based on the user's local timezone, whether using client-side JavaScript, server-side conversion, or a hybrid approach. Time handling is a critical piece of any application, and getting it right will save you from future headaches while ensuring a better user experience!
Happy coding! 🚀
-Gonza
Ready to take your project to the next level?
Contact me
Sr. Software Engineer
Senior software engineer located in Buenos Aires, Argentina. I specialize in building highly scalable web applications and I've been delivering MVPs and helping companies with their digital transformation for the past 7 years. I am proficient in a variety of technologies, including Laravel, Vue.js, Twilio, AWS, React.js, Node.js and MySQL.
If you enjoy the content that I make, you can subscribe and receive insightful information through email. No spam is going to be sent, just updates about interesting posts or specialized content that I talk about.