I need to add the ability to change timezones for North America only. There are a total of six timezones, including Hawaii and Alaska.
I am on the eastern part of the USA, so my timezone is Eastern. When choosing a timezone for my location, I can choose New York, Chicago and a few others. I'm not sure why there are so many different timezones that all resolve to the same offset; unless because of DST.
All I'm basically looking for are these six zones:
EST
CST
MST
PST
AKST
HST
Can someone tell me why there are so many different timezones to choose from that resolve to the same offset?
The list of PHP timezones is pulled from the PECL timezone database. The PECL timezone database comes from the "Olson" database, which is maintained by the IANA organization.
On the IANA website, they state the following about their upkeep of the timezone database:
The Time Zone Database (often called tz or zoneinfo) contains code and
data that represent the history of local time for many representative
locations around the globe. It is updated periodically to reflect
changes made by political bodies to time zone boundaries, UTC offsets,
and daylight-saving rules. Its management procedure is documented in
BCP 175: Procedures for Maintaining the Time Zone Database.
The topic of timezones is further complicated by the fact that not all states use daylight savings (Arizona, Hawaii, Puerto Rico, for example do not use daylight savings).
So, what one could conclude from this is that a timezone for a particular City is based on its zone boundaries, its daylight savings time rules, and other political factors. Thus, just because some city happens to be physically in the west does not mean it is guaranteed to be PST, for example.
Furthermore, by manually setting a western region to PST is technically less maintainable than it would be to set its actual country/city timezone identifier, so that way, should their offset change in the future, your application would continue to set the correct time.
Related
I am writing PHP app that uses timezones. For land based GPS, I use
date_default_timezone_set();
with correct name like Europe/Dublin. However, if the GPS location is not land but it is on the sea, there is no timezone name, but time is offseted from UTC. The calculation is aprox. 1 hour for 15 degrees of longitude. I have calculated UTC offset manually, but I am not able to set it to PHP. I am using date method to print human-readable dates from unix timestamps.
I have found that there are Others timezones names (https://www.php.net/manual/en/timezones.others.php) like Etc/GMT+10, but the PHP documentation states this:
Warning Please do not use any of the timezones listed here (besides UTC), they
only exist for backward compatible reasons, and may expose erroneous
behavior.
Is it safe to use the Etc-based offsets? Or is there any other safe solution? I have not found any. In date_default_timezone_set() comments someone "uses" this: https://www.php.net/manual/en/function.date-default-timezone-set.php#96551 but it seems very ugly.
I am using PHP 7.1.
The time zones in PHP originate from the IANA tz database.
In particular, zones like Etc/GMT+10 originate from the etcetera file in the tz data, which says (emphasis mine):
... These days, the
tz files cover almost all the inhabited world, and the only practical
need now for the entries that are not on UTC are for ships at sea
that cannot use POSIX TZ settings.
Thus, you can indeed and should use them for the purpose you described.
Keep in mind that they only exist for whole-hour offsets from Etc/GMT-14 to Etc/GMT+12, and that the sign in the zone name is opposite from standard conventions. In other words Etc/GMT+10 is actually UTC-10.
One other note. My understanding is that it is common for ships at sea to use a land-based time zone when they are in the territorial waters near such lands, including any daylight saving time adjustment in effect. For example, a ship traveling within the territorial waters of the USA along the Pacific coast should change their clocks to use PST (UTC-8) in the winter and PDT (UTC-7) in the summer. This is modeled by America/Los_Angeles, whereas a pure longitudinal calculation would use UTC-8 year-round (Etc/GMT+8).
All of this is flexible, as the captain of the ship can basically decide the shipboard time at their discretion. See Wikipedia's article on nautical time for more specifics.
You might also want to read here about methods to use GPS coordinates to resolve an IANA time zone. Those that use the Time Zone Boundary Builder project as a data source (such as the Geo-Timezone PHP library) benefit from both nautical time and territorial waters being taken into consideration.
Time zones, offsets, and start end dates for DST (and DST itself existing at all) have changed over the years; and the differences worldwide make up a quite complex grid of zones and UTC offsets for different locations.
Does PHP do anything to calculate this for historic dates? If I put in a date in 1928 for a particular time zone, does PHP calculate what the offset rules were for that location, on that date, in 1928?
PHP has internally stored a list of all timezone offsets changes.
The getTransitions () method returns a numerically indexed array containing an associative array with all transitions.
You can view this list like this:
$timeZoneChicago = new DateTimeZone('America/Chicago');
$transArray = $timeZoneChicago->getTransitions();
echo "<pre>".var_export($transArray,true)."</pre>";
The entries for the future are pure speculation.
Time zones, offsets, and start end dates for DST (and DST itself existing at all) have changed over the years; and the differences worldwide make up a quite complex grid of zones and UTC offsets for different locations.
Yes indeed. The history of time zones on Earth is an extremely complicated subject, as each time zone is delineated by an individual governmental entity. While pretty much everyone now agrees on using Coordinated Universal Time (UTC) as a basis for timekeeping, there is no such standardized agreement when it comes to local time. "Time zones" thus consist of:
A standard offset from UTC
Potentially another offset from UTC that applies at a different time of year, typically called "daylight saving time" or "summer time"
The schedule composing the exact dates and times that transition between standard time and daylight saving time
The cities or geographical borders unto which the time zone(s) apply
Changes to any of of the above, at any point in time
The history of how these rules have changed in the past
Some reasonable speculation about how these rules may remain or change for some period into the future
This subject domain is covered by the "TZ Database", also known as the IANA time zone database, Olson time zone database, zoneinfo, tzdata, tzdb, and a few other names. It is maintained openly by community via IANA, ruled by BDFL governance described in IETF BCP 175 / RFC 6557. It is widely implemented on many different platforms and programming languages.
Does PHP do anything to calculate this for historic dates?
PHP implements the TZ Database via the PECL "timezonedb" package. Each version of PHP is distributed with the latest version of timezonedb already included. It can also be updated independently, but it's often easier just to update to the latest PHP release.
You can read all about this in the PHP Date and Time documentation.
If I put in a date in 1928 for a particular time zone, does PHP calculate what the offset rules were for that location, on that date, in 1928?
That depends on which time zone you are asking about. In general, YES. However, the TZ Database only guarantees data from 1970 forward. However, there are many time zones where prior time zone data is available - when it is known.
The TZDB's policy on this is that they create time zone entries only for zones where the clocks have unique rules after 1970 - even if they differed before this. For zones that do meet this criteria, they backfill with information as it becomes known. There are often discussions on the TZ Mailing List about historical time zone information, and if a reasonable source is provided then often it is corrected in the TZ Database.
As an example the TZDB zone "America/Chicago" has data since 1883. However it also encompases the entire US Central Time zone, of which there were deviations before 1970 for other cities, that are not captured in the TZDB.
As a counterexample, the TZDB zone "Asia/Thimphu" representing Bhutan only has time zone data since 1947. If you ask for a date in 1928, it will use the Local Mean Time (LMT) entry instead. This can be confusing for some, as LMT is calculated based on latitude and longitude, rather than determined by government. In this case Asia/Thimphu has an LMT offset of UTC+05:56:36, whereas after 1947 it was known to have UTC+05:30 offset, until 1987 when it became UTC+06:00.
We have been using IPLEGENCE Database pro to get user timezone based on IP address. Here I have a few unusal time zone off sets. Which are listed below
EST+1
PST-2
PST-1
GMT+12.75
I am not sure what exactly above listed off sets.
Could some one please help me in converting the above time zones to UTC.
Thanks for your time.
Here is a list of time zones. EST is almost always (excepting for those DST overlaps) GMT-5. And GMT is either on UTC, or an hour off (again, DST).
EST+1 = GMT-4
PST-2 = GMT-10
PST-1 = GMT-9
The best you can probably do, if you want to convert it to UTC, is to use the DateTime object.
That is rather a strange way to denote time zones. My guess is that GMT+12:45 refers to the Chatham Islands. Not sure about the others, they could be anywhere.
IMHO, there are a few problems with this type of data:
Time zones are not fixed offsets. When the database refers to EST, they probably mean "US Eastern Time". But that could refer to -5 hours offset for Eastern Standard Time (EST), or -4 hours for Eastern Daylight Time (EDT). By calling it "EST" in the data, they are fixing it to -5, when in fact it might be -4. See "Time Zone != Offset" in the timezone tag wiki.
Time zone abbreviations can be ambiguous. For example, how do I know that "EST" really refers to USA's Eastern Standard Time (-5)? It might refer to Australia's Eastern Standard Time (+10). There is a list here, and you can see there are lots of time zones with the same abbreviation.
IP Geolocation is a "best guess", and does not have the kind of accuracy needed to determine time zone. The time zone in these databases may match the listed coordinates, but you have very little guarantee that the user is actually at those coordinates. It might be giving you the location of a proxy server or network router. This is especially true on corporate networks, where (in some cases) you have an IP in a corporate office in another city and all Internet traffic filters through that IP. You're going to get the timezone of that corporate office - not the time zone of the user. You can read more about IP Geolocation Accuracy here and here.
If you know the coordinates of the user by some other means, such as from GPS data on a cell phone, then you can use one of the several different techniques described here.
I am working on a php (codeigniter) project. I have been doing a lot of work in timezones to convert times between different timezones and the server timezone.
I know how to convert a php timezone identifier to its abbreviation (like Asia/Calcutta to IST). But now, I need the expansion of this abbreviation (Indian Standard Time).
Is there any way to do this in php code, or any webservice to convert it? This is my last step in complete mastery in timezone programming! :)
Edit: As one person who answered pointed out, abbreviations can be ambiguous.. But timezone identifiers aren't. So can I directly convert "Asia/Calcutta" to "Indian Standard Time"? There is no ambiguity in that..
You general, you can't do it because it's ambiguous -- the same abbreviation is used for differente timezones.
Example:
CDT: Central Daylight Time (America/Cancun, America/Chicago, ...)
CDT: Mexico Central Daylight Time (America)
CDT: Cuba Central Daylight Time (America)
CDT: Canada Central Daylight Time (America)
Even IST is not unique:
IST: Irish Summer Time (Europe)
IST: Indian Standard Time (Asia)
IST: Israel Standard Time (not in zic)
There are, however, several heuristics. For instance, PostgreSQL comes with several timezone sets that you can swap depending on the continent of your target audience.
#Munim: Ahh... I didn't know about this. If that is the case, do you
know how to convert a timezone identifier like Asia/Calcutta to Indian
standard time? No ambiguity there..
Yup, (almost) no ambiguity at all. Almost because a timezone identifier might also map to several abbreviations depending on daylight savings and political changes. In PHP, you can do that with either DateTimeZone::listAbbreviations() (but this one isn't very reliable since it shows all the abbreviations used since the dawn of tzdb) or DateTimeZone::getTransitions() - this one is better since if you traverse the array backwards and return the first transition abbr that isn't observing DST.
There is no one-to-one mapping between timezone abbreviations, timezone offsets and timezone expansions. For example, CDT stands for Central Daylight Time which maps to both UTC+10:30 (Australia) and UTC-5 (North America). It has the same abbreviation, but maps to different continents and time offsets.
Similarly, CST is Central Standard Time and Central Summer Time and maps onto the following 3 offsets: UTC+9:30, UTC-6 and UTC+10:30
IST, which you refer to above, is also Irish Summer Time and maps to UTC+1
So, to answer your question, nope, you can't do it. If you really want to achieve mastery in timezone programming, read up on the ISO specifications for the same.
Maye you should look this php function timezone_name_from_abbr()
I know this isn't specific to PHP, but what's the point of using timezones listed like this :http://us2.php.net/manual/en/timezones.america.php? For example "America/Indianapolis" and "America/New_York". What is the problem with EST, EDT, CST, CDT, &c?
'America/New_York' doesn't depend on the date. EST is only valid in winter, while in summer you have to change it to EDT. Other problem with 3 letter codes is, that there are conflicts. EST means Eastern Standard Time, but it might be in America or Australia.
This is just a different timezone format provided by the Zoneinfo database:
The time zones in the database are
given uniform names, such as
“America/New_York”, in an attempt to
make them easier to understand by
humans and to remove ambiguity.
Time zones or daylight savings time start/end dates of cities might change (it did occur in the past) but the cities are likely to remain at the same location.
All regions within a timezone don't follow the same rules. For example, Arizona does not observe Daylight Saving Time.
http://us2.php.net/date_default_timezone_set
Quote from page: Note: Since PHP 5.1.0 (when the date/time functions were rewritten), every call to a date/time function will generate a E_NOTICE if the timezone isn't valid, and/or a E_STRICT message if using the system settings or the TZ environment variable.
"America/Indianapolis" and "America/New_York" are called TZID (Timezone Identifier) from the tz database (also called zoneinfo database or IANA time zone database or Olson database).
The tz database partitions the world into regions where local clocks have all been the same since 1970.
This means that when specifying a TZID, you can accurately and without ambiguity date any local event in the world occurring since 1 January 1970 (Unix Epoch).
This may seem convenient together with a Unix timestamp. Yet, beware of 32 bits programs as they will report negative values with the year 2038 problem.
"EST", "EDT", "CST" and "CDT" are often abbreviations of The Microsoft Windows Time Zone Database and lead to ambiguities as they aren't unique (compare "Central Standard Time", "Central Summer Time", "China Standard Time" and "Cuba Standard Time").
More advantages/disadvantages are given on https://stackoverflow.com/tags/timezone/info.