PHP: Get current locale using timezone - php

I am using timezone to get exact time of a user according to his timezone. I have a drop down list to select timezone for users and showing their current time as they selected their timezone. The code i am using is:
$timezone = 'America/New_York';
date_default_timezone_set($timezone);
echo date('H:i:s A');
It is working fine. I want to get locale of that user using timezone in the same way I am getting current time for that timezone.
How can I achieve the current locale using timezone? Does PHP have any kind of solution to get current locale using timezone?

Locale and time zone are orthogonal. You cannot determine one from the other.
America/New_York means that the user's local time is aligned to New York City, which happens to be called "Eastern Time" in the United States, which is 5 hours behind UTC during standard time and 4 hours behind UTC when daylight saving time is in effect.
en-US (or en_US) means that the user speaks English, with cultural dialects (word choice, numbers, dates, etc.) of the United States. For example, en-US uses MM/DD/YYYY date format, and en-GB uses DD/MM/YYYY date format, but we both call our first month "January", while es-MX calls their first month "enero".
I could very well be an English speaking American visiting Japan, thus my time zone would be Asia/Tokyo even though my local would still be en-US.
Aside: A hyphen (-) is the correct character to split language and country codes in a locale identifier. Though some implementations have substituted an underscore (_), this is not correct by the IETF language tag specification.

Related

querystring GMT datetime in Summer

I need to send a querystring parameter to our API server which is taking times in GMT format.
I am a bit confused about what values I need to send during the summertime, since the dates are in GMT format.
Let's assume we are in London (UK), it's 3PM, and it's the 15th of May
2016.
Is the correct date value:
?date=2016-05-15T15:00:00Z
or
?date=2016-05-15T15:00:00+01:00
or
?date=2016-05-15T16:00:00Z (assuming I always want to use the Z "Zulu Time")
Since London is in BST on that date, then 2016-05-15T15:00:00+01:00 would be the most fully qualified correct form.
If you were to normalize that to UTC, then it would become 2016-05-15T14:00:00Z. Z is equivalent to +00:00, so you have to adjust the hour by the inverse of the original offset.
2016-05-15T15:00:00Z is incorrect, as that is an hour later.
As to which of the two correct forms are more correct for your particular API, there's no way to answer that as you gave no details about how the API is designed, what language it's implemented in, what code is parsing the input, etc. In many cases, either would be accepted. However if the API requires to know local time as well as the universal time, then only the 2016-05-15T15:00:00+01:00 for would convey both.
Also, recognized that there's no such thing as "GMT format". GMT is a time zone, equivalent to UTC+00:00. What you actually have here is a string in ISO8601 extended format, also specified under RFC3339. This is commonly said to be the "ISO format".

Get longer time zone name in PHP

Given a time zone abbreviation like "EST", I can get "America/New York" by using timezone_name_from_abbr. Is there any function that returns something like "Eastern Standard Time"?
In general, you should not trust the timezone_name_from_abbr function, because it only returns the first entry that it finds with a matching abbreviation. Time zone abbreviations are not unique. For example, there are 5 different time zones that share the abbreviation "CST". See this list of abbreviations on Wikipedia for even more examples of ambiguity.
As a specific case for PHP, consider the abbreviation "IST". One might expect timezone_name_from_abbr("IST") to return "Asia/Kolkata", representing Indian Standard Time. However, it actually returns "Asia/Jerusalem", representing Israel Standard Time. Both time zones use the IST abbreviation, but "Asia/Jerusalem" comes first alphabetically.
With that in mind, you should now see why it would also not be practical for a function to return "Eastern Standard Time" given only "EST". While it might be possible for EST, it won't work in all cases. Also consider that "Eastern Standard Time" is in English, and there are other abbreviations and textual descriptions for different languages.
There is a project that contains the information you're talking about, which is from Unicode, and called the Common Locale Data Repository (or CLDR). Using CLDR data, you would be able to write functions that that accept a time zone identifier such as "America/New_York", and a language/locale code such as "en-US", and return the abbreviations "ET", "EST" and "EDT", and the names "Eastern Time", "Eastern Standard Time", and "Eastern Daylight Time". You would then need to decide which name and abbreviation to use, based on the context and/or specific time you were talking about.
I've written such a library for .NET, called TimeZoneNames. You would need something similar for PHP. I don't know of a particular one to recommend for PHP, but perhaps someone has written one, or perhaps you can create the functions you need by directly consuming the CLDR source data.
This was something I was after for some time and seeing someone else is looking for the same functionality it was the last push needed :)
webit4me/timezone, is a PHP tool which can help to get the given timezone's name, location or offset.
The tool also provides a workaround for timezones with similar abbreviations.
i.e. In Matt's example of IST which we have 3 different timezones
India Standard Time (UTC +5:30)
Irish Standard Time (UTC +1:00)
Israel Standard Time (UTC +2:00)
the default IST object will refer to the first occurrence and then we will have 2 more objects IST100 and IST200 to address Irish and Israel standard times. Please note the 100 and 200 suffixes are coming from the timezone's offsets e.g. UTC +1:30 would be 130.
Hope this package will be helpful, and please feel free to tag along and contribute adjustments if required to http://github.com/webit4me/timezone
Getting the longer name from the abbreviation is unreliable, But if you use the DateTime object, and the long name is used when setting the default timezone, or in creating the DateTime object. Using T in the format string will get you the 3-letter abbreviation, BUT you can get the long name like this:
date_default_timezone_set('America/Chicago');
$date = new DateTime('2/3/2022 02:11:17');
echo "\n" . $date->format('Y-m-d h:i:s T');
/* Displays 2022-02-03 02:11:17 CST "; */
$t = $date->getTimezone();
echo "\nTimezone: " . $t->getName();
/* Displays Timezone: America/Chicago */

PHP - ew DateTimeZone() with UTC-5 or UTC+5

How I can create a new date with different timezone? I have tested many ways, but doesn't work, example
$date = new DateTimeZone('UTC+5');
My goal is to create the $date, then convert it to "UTC-5" format.
UTC+5 is not a timezone, it's an offset. A location on earth, say, New York, America, has a local time which is x hours different from the UTC standard time. That's the offset, like UTC-5. However, this offset changes throughout the year based on daylight saving time. In winter the offset may be -5, but in summer -6. A timezone is something which describes this clearly, it's a ruleset for what offset the local time is to UTC and when that offset changes. A timezone is specific to a location and is called, for example, America/New_York.
Therefore, working with "UTC-5" offsets is pretty meaningless, and what you really want to do is use a timezone for the location you're working with.

Converting GMT value for DateTimeZone?

I'm currently using this to convert a timestamp to a user's defined timezone. My problem is that DateTimeZone() requires a timezone like Europe/Vienna or America/Chicago:
$date = new DateTime("#".$timestamp);
$date->setTimezone(new DateTimeZone("America/Chicago"));
I already looked into supported timezones on http://us3.php.net/manual/en/timezones.php but there are so many of them and I don't want users to browse the whole list.
Is there a simple way converting e.g. GMT+1:00, GMT-4:30 or GMT+5:45 to a correct value for DateTimeZone().
Or is it better to use an array list like I found here: Convert selected time and timezone to a set timezone
Is it better to use UTC or GMT in general for the user to pick?
Thanks!
You should probably obtain the user's real timezone (selected from the complete list). Using only a static offset from UTC you will not be able to follow the correct daylight savings time rules for the user's location.
PHP's DateTimeZone doesn't appear to accept POSIX timezone strings so it looks like you're stuck with predefined timezones.
Look in /usr/share/zoneinfo/Etc. There are a bunch of timezones predefined there for UTC plus and minus an integer. The only gotcha is that the sense of + and - is reversed from the normal convention. So just use, for example, "Etc/GMT-9" for a generic timezone with offset +0900.
This doesn't handle all of the possible timezones, like Nepal's weird +0545 but it looks like it's the best option that's easily accessible.
I don't think there's another way to pass a timezone. I think the time zones used in PHP have to be location-based to determine the DST settings along with the offset.
However, you can still present the options as GMT+1:00 etc to your users. And you can narrow down the list to only the much-used options (UTC, GMT, PST, etc).

How do I show datetime in the same time zone as user using PHP or javascript?

Suppose now I've got the datetime to show like this:
2010-05-29 15:32:35
The the corresponding time zone can be get by date_default_timezone_get,
how do I output the result in the same time zone as user's browser so that users don't get confused?
There is no reliable way to read the user's locale timezone settings from PHP or JavaScript.
In JavaScript you can read the offset between UTC and the time in the user's current timezone, but that doesn't give you a timezone name, so you're left either leaving the timezone identifier off (making the times completely ambiguous) or including it is an explicit offset like UTC+01:00, which is ugly, and still doesn't take care of changing timezones over different DST periods.
As bobah says, you can use toLocaleString() on a JavaScript Date to output it in the client's real desktop timezone. However, this way you get no control at all over the date formatting. For example on my machine Chrome outputs the unwieldy:
Sat May 29 2010 15:03:46 GMT+0200 (W. Europe Daylight Time)
Whereas Opera just coughs up:
29/05/2010 15:03:46
Which, as it doesn't state the timezone at all, is uselessly ambiguous. IE is similarly terse, and Safari states no timezone either. Firefox does for me on Linux, but not on Windows. Argh.
So if you need reliability the only way to handle timezones is to let the user manually choose one in their site settings, then convert from UTC to that timezone when you're producing a page for them. You can make a guess in JavaScript as to which the most likely of some common timezones it might be (see this question for strategies), but you can't guarantee you'll be right.
You can pass UTC timestamps to the page and convert them with JavaScript. I used this trick once and was happy with the result. There is a constructor of JavaScript Date taking UTC timestamp. For UTC timestamp generation from PHP one may use gmmktime().

Categories