Jump to content

Created Date - how to get local timezone of browser? - Page created via API


Erik Richter
 Share

Recommended Posts

Hey Guys!

Hopefully someone can point me to the right direction.

On my Website logged-in users can publish posts, like facebook or twitter on the frontend. These posts are created as pages via API.

Since I have visitors/users from different places of the world, I need to have the created-date of the page respecting their timezone. Anyone has an idea how to grab the visitors/browsers timezone/time and use it for $page->created instead of server time?

Thank you so much in advance!

Link to comment
Share on other sites

JavaScript to the rescue 😄 Have a look at this: Intl.DateTimeFormat https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat and in particular this example in SO:

https://stackoverflow.com/a/34602679

const tz = Intl.DateTimeFormat().resolvedOptions().timeZone

As usual, won't work in all browsers, you know, the usual suspects... 😉 

  • Like 3
Link to comment
Share on other sites

I would go with the great Carbon library and handle the timezone conversion in PHP.

https://carbon.nesbot.com/docs/#api-timezone

$tz = new CarbonTimeZone('Europe/Zurich'); // instance way
$tz = CarbonTimeZone::create('Europe/Zurich'); // static way

// Get the original name of the timezone (can be region name or offset string):
echo $tz->getName();                 // Europe/Zurich
echo "\n";

// toRegionName returns the first matching region or false, if timezone was created with a region name,
// it will simply return this initial value.
echo $tz->toRegionName();            // Europe/Zurich
echo "\n";
// toOffsetName will give the current offset string for this timezone:
echo $tz->toOffsetName();            // +02:00
echo "\n";
// As with DST, this offset can change depending on the date, you may pass a date argument to specify it:
$winter = Carbon::parse('2018-01-01');
echo $tz->toOffsetName($winter);     // +01:00
echo "\n";
$summer = Carbon::parse('2018-07-01');
echo $tz->toOffsetName($summer);     // +02:00

// With no parameters, a default timezone is created:
echo new CarbonTimeZone();           // UTC
echo "\n";
echo CarbonTimeZone::create();       // UTC

 

Link to comment
Share on other sites

1 hour ago, Sergio said:

I would go with the great Carbon library and handle the timezone conversion in PHP.

Hi @Sergio, just for clarity, Carbon will work with what you hand to it, right? i.e., it has no way of knowing a user's (browser client) TZ.

  • Like 1
Link to comment
Share on other sites

1 hour ago, kongondo said:

Hi @Sergio, just for clarity, Carbon will work with what you hand to it, right? i.e., it has no way of knowing a user's (browser client) TZ.

Hi @kongondo, sure, but he mentioned "logged-in users can publish posts" so I think he can capture the user timezone settings on the server side, and/or, give the user to overwrite this preference on admin.

EDIT: sorry, I misread it. You are right, @kongondo! my bad!

Link to comment
Share on other sites

@kongondo@Sergio thank you guys!

Users are logged in, but only use the fronend of the website. Would best practice be to store the users time in a hidden field (get it via javascript), submit it with the form, save it as a variable to php, do the $p->save and after that change the created date with the one from the variable and save again?

Link to comment
Share on other sites

If you're dealing with multiple timezones I'd strongly suggest not involving the db in it.

There are two types of datetimes: absolute time (times you want to compare with each other even across timezones) and wall time (11 o'clock stays 11 o'clock for your user). Because timezone defintions can potentially change for future datetimes it's not always as easy to keep both properties as one might think.

If only the first one is important to you you should keep everything in UTC.

If only the last one is important you could use a datetime in the timezone of the user, but it's rarely the case you don't compare timestamps or it doesn't become a requirement (e.g. for ordering).

For past datetimes it's enough to store a utc timestamp and the timezone of the user to get to both the absolute time and the wall time as timezone defintions rarely change in retrospect.

For future datetimes you'd need to make sure to save enough information so you can detect changes in the timezone definition when they happen. Then you or your user can decide if absolute time or wall time was meant to be consistent.

  • Like 5
Link to comment
Share on other sites

@LostKobrakai thanks for the explanation! very helpful.

Actually I created a second datetime field now, where I store the walltime of the user when the post is created. I just use this field then to display the time on frontend, instead of created.

Messing with the actual created date could really make problems - thanks for the insights - especially because you still want to keep the real "order" (dependend on UTC or a universal time) of posts, even tho individual local time is different.

 

  • Like 2
Link to comment
Share on other sites

  • 11 months later...

This should not really be a problem for timestamps like created_at though given they're not in the future. You'd still need to know the UTC datetime and the users timezone, but the offset should not change. A problem is storing a datetime today pointing to a day e.g. 10 years in the future. Within those 10 years the definition of timezones might change and what you though would be the offset in 10 years might not turn out to be the offset anymore.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...