Каковы "стандартные" сокращения часового пояса?
Я сохраняю часовой пояс по смещению от UTC для приложения, использующего этот раскрывающийся список:
<select id="timezone" name="timezone" >
<option value="-12">[UTC - 12] Baker Island Time</option>
<option value="-11">[UTC - 11] Niue Time, Samoa Standard Time</option>
<option value="-10">[UTC - 10] Hawaii-Aleutian Standard Time, Cook Island Time</option>
<option value="-9.5">[UTC - 9:30] Marquesas Islands Time</option>
<option value="-9">[UTC - 9] Alaska Standard Time, Gambier Island Time</option>
<option value="-8">[UTC - 8] Pacific Standard Time</option>
<option value="-7">[UTC - 7] Mountain Standard Time</option>
<option value="-6">[UTC - 6] Central Standard Time</option>
<option value="-5">[UTC - 5] Eastern Standard Time</option>
<option value="-4.5">[UTC - 4:30] Venezuelan Standard Time</option>
<option value="-4">[UTC - 4] Atlantic Standard Time</option>
<option value="-3.5">[UTC - 3:30] Newfoundland Standard Time</option>
<option value="-3">[UTC - 3] Amazon Standard Time, Central Greenland Time</option>
<option value="-2">[UTC - 2] Fernando de Noronha Time, South Georgia & the South Sandwich Islands Time</option>
<option value="-1">[UTC - 1] Azores Standard Time, Cape Verde Time, Eastern Greenland Time</option>
<option value="0">[UTC] Western European Time, Greenwich Mean Time</option>
<option value="1">[UTC + 1] Central European Time, West African Time</option>
<option value="2">[UTC + 2] Eastern European Time, Central African Time</option>
<option value="3">[UTC + 3] Moscow Standard Time, Eastern African Time</option>
<option value="3.5">[UTC + 3:30] Iran Standard Time</option>
<option value="4">[UTC + 4] Gulf Standard Time, Samara Standard Time</option>
<option value="4.5">[UTC + 4:30] Afghanistan Time</option>
<option value="5">[UTC + 5] Pakistan Standard Time, Yekaterinburg Standard Time</option>
<option value="5.5">[UTC + 5:30] Indian Standard Time, Sri Lanka Time</option>
<option value="5.75">[UTC + 5:45] Nepal Time</option>
<option value="6">[UTC + 6] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time</option>
<option value="6.5">[UTC + 6:30] Cocos Islands Time, Myanmar Time</option>
<option value="7">[UTC + 7] Indochina Time, Krasnoyarsk Standard Time</option>
<option value="8">[UTC + 8] Chinese Standard Time, Australian Western Standard Time, Irkutsk Standard Time</option>
<option value="8.75">[UTC + 8:45] Southeastern Western Australia Standard Time</option>
<option value="9">[UTC + 9] Japan Standard Time, Korea Standard Time, Chita Standard Time</option>
<option value="9.5">[UTC + 9:30] Australian Central Standard Time</option>
<option value="10">[UTC + 10] Australian Eastern Standard Time, Vladivostok Standard Time</option>
<option value="10.5">[UTC + 10:30] Lord Howe Standard Time</option>
<option value="11">[UTC + 11] Solomon Island Time, Magadan Standard Time</option>
<option value="11.5">[UTC + 11:30] Norfolk Island Time</option>
<option value="12">[UTC + 12] New Zealand Time, Fiji Time, Kamchatka Standard Time</option>
<option value="12.75">[UTC + 12:45] Chatham Islands Time</option>
<option value="13">[UTC + 13] Tonga Time, Phoenix Islands Time</option>
<option value="14">[UTC + 14] Line Island Time</option>
Используя PHP, у меня нет действительно простых способов конвертировать их в сокращения часовых поясов, мой единственный вариант сделать это программно - отсортировать список из примерно 400 сокращений часовых поясов. Кто-нибудь знает список, который сопровождает это раскрытие того, что является каждым из часовых поясов, и каковы они, когда происходит переход на летнее время? (Я предполагаю, что мне нужно определить оба списка вручную)
РЕДАКТИРОВАТЬ: проанализировал этот список до одного аббревиатуры для каждого часового пояса, но они не являются "популярными".
Мой новый список
[-12] => kwat
[-11] => bst
[-10] => ahst
[-9.5] => ckhst
[-9] => ahdt
[-8] => akdt
[-7] => east
[-6] => cst
[-5] => act
[-4.5] => ant
[-4] => acst
[-3.5] => negt
[-3] => adt
[-2] => addt
[-1] => azost
[-0] => azomt
[1] => bst
[2] => bdst
[3] => amt
[3.5] => irst
[4] => adt
[4.5] => aft
[5] => aktt
[5.5] => ist
[5.75] => npt
[6] => aktst
[6.5] => burt
[7] => almst
[8] => bnt
[8.75] => cwst
[9] => cdt
[9.5] => cast
[10] => chost
[10.5] => cst
[11] => anat
[11.5] => lhst
[12] => anast
[12.75] => chast
[13] => anast
[14] => anast
Код:
$abbr = DateTimeZone::listAbbreviations();
$offsets=array('-12','-11','-10','-9.5','-9','-8','-7','-6',
'-5','-4.5','-4','-3.5','-3','-2','-1','-0','1','2','3','3.5',
'4','4.5','5','5.5','5.75','6','6.5','7','8','8.75','9','9.5',
'10','10.5','11','11.5','12','12.75','13','14');
$new = array();
$count = 0;
$found = false;
while($count < count($offsets))
{
foreach($abbr as $k => $v)
{
foreach($v as $tz)
{
if($tz['offset'] == $offsets[$count]*3600)
{
$new[$offsets[$count]] = $k;
$found = true;
break;
}
}
if($found)
{
$found = false;
break;
}
}
$count++;
}
print_r($new);
2 ответа
Каковы "стандартные" сокращения часового пояса?
Для этого нет стандартов. Сокращения часового пояса официально не согласованы никем. Некоторые из них используются в IANA TZDB, но многие из них были выбраны случайным образом. Часто идут споры о том, какие сокращения следует использовать. Например, посмотрите, сколько сообщений было об австралийских сокращениях в архивах списков за апрель 2013 года.
Другой список сокращений часовых поясов можно найти здесь. Если вы посмотрите внимательно, вы увидите, что многие из них неоднозначны. Например, CST
может быть "Центральное стандартное время" (США), "Стандартное китайское время" или "Стандартное время Кубы". EST
может быть "Восточное стандартное время" (США) или "Восточное стандартное время" (Австралия).
Некоторые не австралийцы могут предпочесть AEST
но кто это скажет A
должно быть для Австралии, а не для Америки?
Еще один очень распространенный пример, некоторые люди используют HAST
для Гавайев, в то время как другие используют HST
потому что им наплевать на Алеутские острова на Аляске (что является A
должен представлять).
Дело в том, что любой список сокращений часовых поясов, где бы вы ни находились, будет субъективным и самоуверенным. Там нет стандарта.
Я сохраняю часовой пояс по смещению для приложения, использующего этот раскрывающийся список:
Пожалуйста , не делай этого. Часовой пояс не является смещением, и их гораздо больше, чем 24. Пожалуйста, прочтите вики-тег с часовым поясом, особенно раздел под названием "Часовой пояс!= Смещение".
Из ваших комментариев:
Я понимаю это сейчас, однако остальная часть моей логики приложения уже зависит от этого таким образом, и у меня есть только сегодня, чтобы завершить это, так что нет времени, чтобы изменить это.
Тогда многие ошибки будут продолжать присутствовать в вашем приложении. Вы просто не можете сделать это надежно - даже если ваше приложение просто работает в США. Неважно, на каком языке или платформе вы находитесь, любая реализация, которая делает это, будет иметь много ошибок преобразования.
Я в порядке с жестким кодированием этих массивов, я просто не знаю, какие популярные зоны находятся за пределами США, я подумал, что такой список уже где-то существует.
Когда дело доходит до часовых поясов, вам не нужно ничего кодировать жестко. Правила часовых поясов постоянно меняются, потому что они контролируются политиками в каждой стране мира. Обновления выпускаются несколько раз в год для базы данных часовых поясов IANA. Что касается PHP, то в документации PHP ясно, какая версия доступна в данный момент, и что обновления обрабатываются с помощью timezonedb PECL, которая получает данные из IANA.
Что касается того, что является "популярным" - это также очень субъективно. Зоны в TZDB все там по той или иной причине. Единственное место, которое я знаю, пыталось ограничить это - ActiveSupport::TimeZone из Ruby on Rails. Они утверждают, что имеют "значимое подмножество 146 зон", которое вы можете увидеть в MAPPING
постоянная на этой странице. Но они не говорят, по какому процессу они решили, что считается значимым, и есть явные упущения. Если вы точно не знаете, где будут находиться все ваши пользователи, я бы не стал решать, какие зоны ограничивать.
Если то, что вам нужно, это что-то иное, чем выпадающий список всех 578 зон в TZDB, вы можете попробовать один из следующих подходов:
Представьте два выпадающих списка. Первый, чтобы выбрать страну. Второй, чтобы выбрать зону в этой стране. В PHP вы можете видеть это, когда вы звоните
DateTimeZone::listIdentifiers
, он принимает необязательный$country
параметр для фильтрации списка.Хороший пример этого в настройках Календаря Google:
Используйте элемент управления на основе карты, чтобы ваш пользователь мог выбирать свой часовой пояс по местоположению. Их много, но мой любимый - JavaScript.
Например, это может выглядеть так:
Обратите внимание, что пока он показывает аббревиатуру TZDB EDT
здесь - это просто используется для удобства отображения. Под капотом вы выбираете значение как America/New_York
,
В конечном итоге для каждого пользователя необходимо сохранить ключ часового пояса IANA, например: America/New_York
, Вы не можете делать правильные преобразования часового пояса только с помощью значения -5
потому что у вас нет всех правил, когда он переключится на -4
,
Обновить
Одна вещь, которую я не понял из вашего исходного поста, но вы пояснили в комментариях, что вы используете это, чтобы выбрать часовой пояс целевого события. Я думаю, я должен был сначала спросить о контексте. Я подходил к этому с точки зрения выбора одного часового пояса для вашего пользователя, а не конкретного часового пояса для конкретного события.
Все, что вам действительно нужно для того, чтобы событие было в нужный момент, это смещение на этот момент. Таким образом, вы можете использовать раскрывающийся список, подобный тому, который вы указали в своем вопросе, но я бы опускал любые названия зон. Это будет буквально список смещений от UTC-12:00
в UTC+14:00
, Похоже, вы уже определили, что существует также 30-минутное и 45-минутное смещение. Вы можете проверить свои предположения здесь, если хотите.
Однако общая проблема заключается в том, что многие люди не знают, каким должно быть смещение. Поместив список со стандартным смещением для каждого имени зоны, вы можете ввести пользователя в заблуждение, выбрав неправильное смещение. Например, они могут говорить о летней дате, которая должна приходиться на американское восточное дневное время (-4), но вместо этого они выбирают выбор -5, потому что видят "восточное". Так что удаление имен поможет.
Если вы пойдете по пути, который я изначально предлагал, и предложите им выбрать часовой пояс IANA, это будет работать намного лучше для многих сценариев. Однако есть еще один сценарий, о котором вам нужно подумать - как справиться с неоднозначными и недопустимыми временами. Это происходит во время переходов DST.
Например, я мог бы выбрать America/New_York
и выберите время 1:00 AM 3 ноября 2013 года. Существует два разных случая этого из-за запасного перехода (один в EDT в -4 и другой в EST в -5). Таким образом, ваше приложение должно будет проверить это и спросить пользователя, что из двух они имеют в виду. Аналогичным образом, если я введу 10:00 2013 года в 2:00 AM, ваше приложение должно сообщить мне, что в этой зоне этого времени не существует (из-за перехода с упреждением вперед).
При любом подходе, когда дело доходит до фактического сохранения времени события, убедитесь, что вы либо сохранили комбинацию даты-времени-смещения, либо применили смещение, чтобы получить дату-время в UTC. Вы не хотите, чтобы был какой-либо вопрос о том, какой фактический момент времени представлен событием.
Вы можете найти стандартные сокращения часовых поясов, объединенные в один файл - см. мой другой ответ на этот вопрос - https://stackoverflow.com/a/72839900/1112963