I want to set the time zone of the app according to users timezone

in my app i want to set the time zone according to users login time session(['userTimezone']) globally
5 Replies
BuddhaNature
BuddhaNature2w ago
The app's timezone can be changed dynamically in a provider or middleware, but it's not a good idea to do that. The app should represent the timezone of the data, not any single user. When presenting data, you can then present the user's relative time zone based on a helper like ->timezone. Another way to think of this is that the data in the database should be normalized, not relative to any single user.
GHOST-117
GHOST-1172w ago
I have some user at Fiji Standard Time . At some point they are a day ahead of us what if my user made a payment at his time that is a day ahead of my time zone .... if i open my app at the same time it will show me the future date that is wrong in my opinion .............
awcodes
awcodes2w ago
You can certainly do what you think you need to but the most common and recommended approach is to store all date times in UTC. That way it can always be calculated correctly. So, in this case you would display it as the timezone of the logged in user. Not the time it was posted by the end user.
BuddhaNature
BuddhaNature2w ago
@GHOST-117 A different way to look at it is that the order is being place at the same time as you, but shifted relative to the time zone. Ideally, you want to show time relative to you, not them. You want to show them time relative to them, not you. You can also use human readable relative formats. Here's an example:
use Illuminate\Support\Carbon;

$order = Carbon::createSafe(2024, 7, 9, 12, 0, 0, "UTC");

[
"By Date" => [
"UTC" => $order->timezone("UTC")->toDayDateTimeString(),
"Nashville" => $order->timezone("America/Chicago")->toDayDateTimeString(),
"Fiji" => $order->timezone("Pacific/Fiji")->toDayDateTimeString()
],
"Relative" => [
"UTC" => $order->timezone("UTC")->diffForHumans(),
"Nashville" => $order->timezone("America/Chicago")->diffForHumans(),
"Fiji" => $order->timezone("Pacific/Fiji")->diffForHumans()
],
"Relative, 4 parts" => [
"UTC" => $order->timezone("UTC")->diffForHumans(["parts" => 4]),
"Nashville" => $order
->timezone("America/Chicago")
->diffForHumans(["parts" => 4]),
"Fiji" => $order->timezone("Pacific/Fiji")->diffForHumans(["parts" => 4])
]
];
use Illuminate\Support\Carbon;

$order = Carbon::createSafe(2024, 7, 9, 12, 0, 0, "UTC");

[
"By Date" => [
"UTC" => $order->timezone("UTC")->toDayDateTimeString(),
"Nashville" => $order->timezone("America/Chicago")->toDayDateTimeString(),
"Fiji" => $order->timezone("Pacific/Fiji")->toDayDateTimeString()
],
"Relative" => [
"UTC" => $order->timezone("UTC")->diffForHumans(),
"Nashville" => $order->timezone("America/Chicago")->diffForHumans(),
"Fiji" => $order->timezone("Pacific/Fiji")->diffForHumans()
],
"Relative, 4 parts" => [
"UTC" => $order->timezone("UTC")->diffForHumans(["parts" => 4]),
"Nashville" => $order
->timezone("America/Chicago")
->diffForHumans(["parts" => 4]),
"Fiji" => $order->timezone("Pacific/Fiji")->diffForHumans(["parts" => 4])
]
];
Your output will look like this:
[
"By Date" => [
"UTC" => "Tue, Jul 9, 2024 12:00 PM",
"Nashville" => "Tue, Jul 9, 2024 7:00 AM",
"Fiji" => "Wed, Jul 10, 2024 12:00 AM",
],
"Relative" => [
"UTC" => "1 day ago",
"Nashville" => "1 day ago",
"Fiji" => "1 day ago",
],
"Relative, 4 parts" => [
"UTC" => "1 day 9 hours 31 minutes 22 seconds ago",
"Nashville" => "1 day 9 hours 31 minutes 22 seconds ago",
"Fiji" => "1 day 9 hours 31 minutes 22 seconds ago",
],
]
[
"By Date" => [
"UTC" => "Tue, Jul 9, 2024 12:00 PM",
"Nashville" => "Tue, Jul 9, 2024 7:00 AM",
"Fiji" => "Wed, Jul 10, 2024 12:00 AM",
],
"Relative" => [
"UTC" => "1 day ago",
"Nashville" => "1 day ago",
"Fiji" => "1 day ago",
],
"Relative, 4 parts" => [
"UTC" => "1 day 9 hours 31 minutes 22 seconds ago",
"Nashville" => "1 day 9 hours 31 minutes 22 seconds ago",
"Fiji" => "1 day 9 hours 31 minutes 22 seconds ago",
],
]
All of the output above is the exact same time. If you read By Date, it seems like one time is ahead of another by a day, but that's just a quirk of timezones. If you look at the relative parts, you can see that no matter what the time zone translation is, it's all the exact same moment in time. One thing to consider in your panel is to show two times. One local to you and one local to the current order. You can supplement that with a relative time as well.
GHOST-117
GHOST-1177d ago
I have think a bit different way in my bootstrap.js firing an event when the app starts

document.addEventListener("DOMContentLoaded", function () {
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
Livewire.dispatch("updateUserTimezone", {timezone,});
});

document.addEventListener("DOMContentLoaded", function () {
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
Livewire.dispatch("updateUserTimezone", {timezone,});
});
and in my dashboard i have

#[On('updateUserTimezone')]
public function updateUserTimezone($timezone)
{
session(['userTimezone' => $timezone]);
}

#[On('updateUserTimezone')]
public function updateUserTimezone($timezone)
{
session(['userTimezone' => $timezone]);
}
a listner for that and iam setting session usertime zone and in my column i have done some thing like
TextColumn::make('created_at')
->timezone(session('userTimezone'))
->date(),
TextColumn::make('created_at')
->timezone(session('userTimezone'))
->date(),
this.....