Как я могу управлять часовыми поясами в моем веб-приложении?


109

Я ищу лучшее понимание следующей пользовательской истории:

Джон работает в Сиднее. В 9:00 утра он регистрирует событие в веб-приложении, которое работает на сервере в Цюрихе. На следующий день он едет в Нью-Йорк на экстренное совещание, на котором должно быть обсуждено это событие. Во время встречи он ищет событие по дате и времени.

На мой взгляд, здесь есть как минимум две проблемы:

  1. Как мне сохранить отметки времени в базе данных
  2. Как мне представить их в пользовательском интерфейсе

Когда Джон ищет событие, он будет знать, что оно произошло в 9:00, но что он должен ввести в веб-браузере? Он ничего не найдет, если просто введет «9:00» в качестве метки времени, потому что это может быть время Цюриха или Нью-Йорка (поскольку событие не было обнаружено, приложение не может узнать, что оно произошло в Сиднее, поэтому он не может автоматически выбрать правильный часовой пояс).

Как лучше всего запросить у пользователя метку времени, которая может включать часовой пояс?

Вторая проблема - как отобразить результаты. Если командам со всего мира нужно обсудить событие (и найти связанные события, подумайте о взломе, нацеленном на несколько сайтов по всему миру одновременно).

Каков хороший пример отображения меток времени, которые могли быть созданы в другом часовом поясе?

Примечание: пожалуйста, сконцентрируйтесь на удобстве использования требования. Я сам могу вычислить отображение базы данных. В настоящее время я не уверен в рабочем процессе. Он должен запрашивать / представлять необходимую информацию ненавязчивым / интуитивно понятным способом. Если можете, дайте ссылку на существующее веб-приложение, которое уже решает эту проблему.


5
Stack Overflow решает эту проблему, помещая все в UTC. Не всегда удобно, но однозначно однозначно, не сложно реализовать, работает.
Ry-

2
UTC заманчиво, но OTOH, SO никогда не нужно синхронизировать события в нескольких часовых поясах.
Аарон Дигулла 01

3
Что, если одна из вовлеченных стран примет законодательство, изменяющее местное время после того, как мероприятие было запланировано, но до его проведения? Как система должна с этим справиться? en.wikipedia.org/wiki/…
Юлиус Мюссо

1
Этот тип классического вопроса о часовом поясе был настолько забит на протяжении десятилетий в Интернете и в печати, что я удивлен, увидев такой живой вклад и награды по этому вопросу!
BenSwayne

2
Я добавляю дополнительную сложность, указывая на очевидное, а именно на то, что большая часть западного мира меняет часовые пояса дважды в год («летнее время»), и что правила, когда это происходит, не являются ни единообразными глобально, ни обязательно тривиальными, алгоритмически говоря?
fr13d

Ответы:


101

Проблема с хранением меток времени проста: храните их в формате UTC.

Что касается их отображения, имеет смысл взять настройку часового пояса устройства и использовать ее в качестве текущего часового пояса. Тем не менее, рядом с полем «ввод времени» должно быть раскрывающееся меню часового пояса, которое по умолчанию соответствует текущему часовому поясу устройства, чтобы пользователь мог изменить его при необходимости.

Большинство ваших пользователей, вероятно, не будут менять часовые пояса сильно или вообще. По большей части описанная вами ситуация необычна. Реализовав раскрывающийся список с подходящим значением по умолчанию, вы сможете упростить задачу для тех, кто действительно перемещается (потому что они, как правило, лучше понимают часовые пояса, чем человек, не являющийся путешественником).

Фактически, даже лучше было бы сохранить часовой пояс, в котором устройство было установлено при первом запуске вашего приложения, а затем посмотреть, изменится ли он когда-нибудь. Если он изменится, то пользователь, вероятно, путешественник и, вероятно, получит выгоду от раскрывающегося меню часового пояса. В противном случае просто не показывайте раскрывающийся список и по умолчанию используется часовой пояс устройства (потому что пользователю не нужно знать о них). В любом случае настройте приложение, которое позволяет пользователю вручную отображать / скрывать раскрывающийся список часового пояса.


Подводя итог вышесказанному:

  • При первом запуске сохраните, какой часовой пояс установлен на устройстве.
  • Используйте этот часовой пояс как часовой пояс по умолчанию. Всегда предполагайте, что часовой пояс.
  • Если устройство переключает часовые пояса, добавьте раскрывающийся список, чтобы выбрать часовой пояс, в котором находится событие, по умолчанию - собственный часовой пояс устройства.
  • Добавьте параметр, чтобы показать / скрыть раскрывающийся список этого часового пояса вручную.
  • Всегда храните отметки времени в формате UTC.

Что мы подразумеваем под «часовым поясом»? Кажется, используется неоднозначно. Это похоже на ссылку: en.wikipedia.org/wiki/Tz_database Из того, что я могу сказать, «часовой пояс» - это «Область / Местоположение», например «Америка / Нью-Йорк». Это кажется географическим, и это здорово, потому что, например, America / Los_Angeles означает ОБЕ PST и PDT в зависимости от того, работает ли земной шар в летнее время. И если это так, вопрос заключается в том, как мы можем учесть двухгодичные изменения смещения UTC для зон? И как мы называем эти оценки, если они не являются «зонами» географически правильно?
iJames

Это отличный ответ. Есть ли лучший способ хранить информацию о часовом поясе? Например, какой вариант лучше - "Тихоокеанское время" или "Америка / Тихий океан"? Как мне легко преобразовать метку времени в формате UTC в записанный часовой пояс пользователя? Приветствуются любые передовые практики.
Patthebug

28

В наших приложениях мы обычно сохраняем часовой пояс пользователя при первой регистрации, как это часто бывает на сайтах форумов, и всегда отображаем время вместе с часовым поясом .

Что касается хранения дат, лучше всего использовать UTC. Преобразуйте в UTC и вставьте в базу данных. При получении просто конвертируйте время в часовой пояс, установленный для пользователя.

Мне пришлось решить аналогичный вариант использования, когда настраиваемые уведомления, такие как «С Новым годом», можно было отправлять всем пользователям веб-приложения. Поскольку пользователи разбросаны по всему миру, нам нужно было отображать уведомление в соответствии с часовым поясом. Сохранение метки времени в формате UTC отлично послужило нашей цели, без сбоев.

В вашем случае использования, если вы не храните где-то часовой пояс пользователя, вы никогда не сможете точно вернуть результаты поиска, не запрашивая ввод данных пользователем, если только вы не начнете использовать какое-то определение местоположения, такое как gmaps, но это не так. т надежный. Поэтому вам нужно будет каждый раз запрашивать часовой пояс, чтобы пользователь знал, что он вводит на веб-сайте.

Если у вас есть информация о часовом поясе, все веб-приложение должно запускаться с настройкой часового пояса. Следовательно, когда пользователь выполняет поиск 9:00, он будет искать в часовом поясе Сиднея. С другой стороны, если он создает событие, сидя в Нью-Йорке, он создаст событие с часовым поясом Сиднея. Мы решаем такие случаи, всегда отображая часовой пояс при отображении дат.

Надеюсь, поможет! :)


Я думаю, что с добавлением раскрывающегося списка для часовых поясов при поиске и создании событий это правильный путь. (когда мне нужно найти событие, созданное коллегой из Нью-Йорка, я не хочу делать математику сам)
RasmusWL

Это отличный ответ. Есть ли лучший способ хранить информацию о часовом поясе? Например, какой вариант лучше - "Тихоокеанское время" или "Америка / Тихий океан"? Как мне легко преобразовать метку времени в формате UTC в записанный часовой пояс пользователя? Приветствуются любые передовые практики.
Patthebug

11
  1. УНИВЕРСАЛЬНОЕ ГЛОБАЛЬНОЕ ВРЕМЯ. Будь проще.

  2. Используйте часовой пояс, наиболее подходящий для пользователя.

    Если вы знаете, что пользователь будет в Сиднее или поедет в него на мероприятие, то он будет думать в этом часовом поясе при организации транспорта на мероприятие. Тот факт, что они сейчас в Нью-Йорке, в значительной степени не имеет значения. И, конечно же, если ваше приложение показывает даты в разных часовых поясах, оно всегда должно показывать часовой пояс рядом с датой, например, 09:00 EST .

    Если это не слишком загромождает ваш интерфейс, вы можете отображать даты в часовом поясе события и местном часовом поясе, например, 2012-06-13 09:00 EST (2012-06-12 19:00 EDT) .

    Я бы сказал, что поиск - это аналогичная проблема, но с одной оговоркой: мы можем терпеть ложные срабатывания (получение результата, которого не ожидали), но мы не можем терпеть ложноотрицательные результаты (отсутствие ожидаемого результата).

    Опять же, я бы сосредоточился на поиске наиболее подходящего часового пояса для пользователя (например, часового пояса события) и дал бы этим результатам приоритет в результатах поиска, но вы также можете возвращать события, соответствующие другим часовым поясам, которые имеют отношение к пользователю (например, местное время). Если вы сделаете это, вы должны показать дату события в соответствующем часовом поясе, особенно если вы выделите соответствующий текст.


7

Здесь я даю советы по удобству использования, не беспокоясь о возможности реализации.
1. Что касается первого вопроса о хранении событий в базе данных, все согласны хранить его в формате UTC.

2. Чтобы обеспечить наилучшее взаимодействие с пользователем, сохраните историю часового пояса пользователя. Еще лучше, если бы вы могли сохранить метку времени изменения часового пояса. Это позволит нам предоставить пользователю свободу запроса без явного указания часового пояса каждый раз.

Итак, с помощью этих функций, давайте посмотрим, как будет обрабатываться поисковый запрос Джона, содержащий всего "9.00":
С помощью вышеупомянутых функций теперь я знаю, что Джон был в 2 часовых поясах до настоящего времени (или получить список часовых поясов за указанный период). Итак, я переведу 9.00 из часового пояса Сиднея в UTC, запрошу запрос. Также преобразуйте 9.00 из часового пояса Нью-Йорка в UTC, запустите запрос. В результате я покажу Джону 2 строки, показывающие, что он делал в 9.00 в Сиднее и в 9.00 в Нью-Йорке. Строка New York будет пустой в этом случае, но я думаю, что ее все же следует показать пользователю, просто чтобы сообщить ему, что мы также искали этот часовой пояс.

3. Как лучше всего попросить пользователя указать временную метку, которая может включать часовой пояс?

Если его часовой пояс недавно был изменен, всякий раз, когда он входит в приложение, должно выдаваться уведомление о том, что ваш часовой пояс по умолчанию изменяется на собственный часовой пояс.
Допустим, при создании события пользователь выбирает часовой пояс из раскрывающегося списка. Позволяет не обременять пользователя, предоставляя варианты всех часовых поясов мира. Первым вариантом раскрывающегося списка должен быть текущий часовой пояс устройства пользователя. после этого часовые пояса из его истории часовых поясов, затем UTC, а затем оставшиеся часовые пояса, которые он никогда не использовал до настоящего времени.

4. Как отобразить результаты, если командам со всего мира нужно обсудить мероприятие:

Я хотел бы разделить этот вариант использования на количество команд 2 или более 2.
Для всего 2 команд я бы предпочел, чтобы каждая команда видела временную метку в своем местном часовом поясе и часовом поясе другой команды. (Я лично предпочитаю говорить в часовом поясе человека на другом конце для его удобства при планировании встречи). Для более чем двух команд лучше использовать более общий часовой пояс, то есть UTC. Таким образом, в этом случае каждый пользователь должен видеть метку времени в 2 часовых поясах, в формате UTC и в своем часовом поясе по умолчанию.

Эти предложения даны с намерением, чтобы пользователю не нужно было производить какие-либо вычисления в его местном времени, но в то же время он должен иметь возможность свободно общаться с другими пользователями в их предпочтительном часовом поясе.


2
+1 Это очень интересная идея, потому что я знаю, что пользователь ввел событие в 9:00 в Сиднее, поэтому, когда тот же пользователь ищет время (без явного часового пояса), я должен предположить, что он имеет в виду «где я был в в то время »
Аарон Дигулла

4

Хорошо, у меня другой подход, чем у других:

Во-первых, я предполагал несколько вещей заранее.

У человека, который перечисляет событие, есть смартфон (если это браузер, мне не нужно делать эти предположения) с:

  1. GPS

  2. Возможность HTML5.

  3. Возможность Javascript

Как мне сохранить отметки времени в базе данных?

Решение: Очевидно, UTC , я наложил процедуру ниже:

Шаг 1. Используйте геолокацию пользователя с помощью Geolocation API.

    window.onload = getMyLocation;

    function getMyLocation() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(displayLocation);
        } else {
            alert("Oops, no geolocation support");
        }
    }

    function displayLocation(position) {
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
        var div = document.getElementById("location");
        div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: " + longitude;
    }

Шаг 2. Укажите (Long, Lat) в качестве аргументов для некоторых (Lat, Long) API TimeZone, например Yahoo API. (Широта (используйте Флаг R, чтобы преобразовать Широту в Часовой пояс), чтобы получить часовой пояс пользователя.

=> Часовой пояс пользователя определяется без ввода данных пользователем (я использую это , потому что вы не можете просто предположить , что пользователь знает часовой пояс места , где он живет, я знал , что мой часовой пояс только после нескольких месяцев или что - то в этом месте: P, довольно тупой! )

Каждая таблица событий имеет Timezone, Eventтак что можно также CityName создать другую таблицу базы данных с классификацией на основе CityNames. Итак, здесь у пользователя будет два столбца

|---------------------------------------|
|_____NewYork________|______Sydney______|
|                    |                  |
|Event 1             |  Event 2         |
|____________________|__________________| 

Для UI

=> использовать Google Calendar API или некоторые из Calendar API

Связанные материалы:

  1. Определите часовой пояс по широте / долготе без использования веб-сервисов, таких как Geonames.org

  2. Поиск часового пояса по широте и долготе

Я знаю, что это просто демонстрация идеи, как решить эту проблему. Но посмотрите, насколько точным и легким он становится для пользователей, когда часовой пояс определяется с помощью API-интерфейсов устройства.

Надеюсь, поможет!


4
Найти чей-то часовой пояс без геолокации довольно просто. new Date().getTimezoneOffset()дает в минутах отстает от UTC.
Ry-

@minitech, это правда, но что, если событие происходит в Нью-Йорке и где-то на юге, где находится тот же часовой пояс. Я использую геолокацию, чтобы вы могли точно определить город (даже точно), часовой пояс и основать на нем свою таблицу db. Я хочу свести к минимуму ввод данных пользователем с помощью API устройства, чтобы повысить эффективность приложения.
uday

Так? Время будет одинаковым в обоих местах, так что проблем нет. -1
Ry-

@minitech, вы можете увидеть эту ссылку, почему я рекомендую использовать API устройства, а не другие методы. webdirections.org/sotmw2011
Удай

2
Хорошо, но проблема здесь не в получении города пользователя. Речь идет только о часовом поясе. Использование API геолокации, который не работает в каждом браузере / компьютере, а затем перенаправление на API календаря - плохой способ получить часовой пояс пользователя, если он доступен в одной строке кода.
Ry-

2

В этом конкретном случае я бы сохранил как местное время, так и время в формате UTC. UTC является довольно важным и используется для синхронизации и преобразования времени в текущий часовой пояс. Local используется для поиска и получения дополнительной информации, например:

У вас встреча:

12:00 Monday (UTC)
9:00 Monday (Sydney, creation local time)
11:00 Monday (Zurich, local time)

или что-то вроде того. Другой способ - сохранить часовой пояс создания и преобразовать его во время выполнения (это особенно лучше, если пользователь изменит время встречи). В любом случае основная причина - возможность восстановить исходное время создания, чтобы пользователь мог к нему обратиться.


2
  1. Как мне сохранить отметки времени в базе данных

При создании события я бы сохранил время UTC и местный часовой пояс (он же creation time zone). Я бы использовал то, что я сохранил, чтобы преобразовать время UTC в местное время (иначе creation time) и сохранить его вместе со временем UTC и creation time zone.

ПРИМЕЧАНИЕ. Я могу сохранить местное время с самого начала, но когда пользователь выполняет поиск события, я надеюсь, что существует преобразование в местное время. Я также надеюсь, что сервер может определить, в каком часовом поясе находится клиент.

  1. Как мне представить их в пользовательском интерфейсе

Когда пользователь ищет «9:00», я бы искать события , которые включают «9:00» в любом формате UTC ИЛИ creation time ИЛИ по местному времени. Для результатов я бы отобразил одну таблицу результатов вcreation time (Это предназначено для отображения временных меток, которые могли быть созданы в другом часовом поясе, поскольку мы предполагаем, что пользователь ищет, в какое время он создал событие, где бы он ни находился.) и отобразить вторую таблицу результатов ниже со связанными результатами, возможно, с заголовком «Не то, что вы ищете? См. связанные результаты» (они включают оставшиеся результаты в формате UTC и результаты по местному времени).

В целом, я бы отобразил время UTC, местное время, creation timeи creation time zone(то есть местное время и часовой пояс события, в котором оно было создано), отсортированные по времени UTC, чтобы вы могли видеть, какое событие наступит первым, в случае двух разных События были запланированы на 9:00 в двух разных часовых поясах.


1
+1 Мне нравится идея показывать все события во всех часовых поясах, где совпадает местное время; Я просто недоволен SQL ( BETWEENусловия 24x ).
Аарон Дигулла,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.