I use this method using js on the frontend to get the utc offset in minutes. It gives me a result like -300 for UTC+500
const d = new Date();
let diff = d.getTimezoneOffset();
Now how do I make the date in php using this offset? More specifically, how do I convert this offset to something acceptable by a solution like this:
$usersNow = new DateTime('now', new DateTimeZone('+0300'));
Do I have to manually get my offset to a string like this?
2
Answers
Since there are other ways to achieve the same goal, for the sake of saving time for others, here is another solution for javascript and php.
Frontend, get the time zone instead of offset
On the backend:
The
DateTimeZone
class is a wrapper around functions in a library by Derick Rethans called "timelib", so we can check the source code to confirm our options.The constructor first calls timelib_parse_zone which recognises "GMT+", "GMT-", "+", and "-" as prefixes for offsets, and passes the remaining string to timelib_parse_tz_cor.
As pointed out in a comment by Paolo, the JS Date.getTimezoneOffset function returns its offset with the opposite sign from most other notations: -300 represents an offset of 300 minutes ahead of UTC. We can therefore begin our string with "+" for a negative input, and "-" for a positive input, then format the rest of the value ignoring sign.
That function handles the following formats, based on the length of the string:
If you only care about whole-hour offsets, the simplest format would be to include only the hours (the "H" and "HH" cases). However, there are no formats that only have minutes.
To cover all timezones, you’ll need one of the formats that includes both hours and minutes.
Looking at the code, a value of "+123" will be interpreted the same as "+01:23", but it could theoretically mean "+12:03" instead, so it’s best to avoid that ambiguity. We can either insert zeroes to make a fixed length format like "HHMM", or we can include the ‘:’ separator, which allows one or two digits on either side.
A verbose implementation could therefore look like this: