Як я можу обробляти часові пояси у своєму веб-сайті?


104

Я шукаю кращого розуміння наступної історії користувача:

Джон працює в Сідні. О 9:00 ранку він реєструє подію у веб-додатку, який працює на сервері в Цюріху. Наступного дня він вирушає до Нью-Йорка на екстрену зустріч, на якій слід обговорити подію. Під час зустрічі він здійснює пошук події за датою та часом.

Як я бачу, тут є щонайменше два питання:

  1. Як слід зберігати позначки часу в базі даних
  2. Як мені їх представити в інтерфейсі користувача

Коли Джон здійснює пошук події, він дізнається, що це сталося о 9:00, але що йому слід ввести у веб-браузері? Він нічого не знайде, коли він просто вводить "9:00" в якості часової позначки, тому що це може бути час Цюріха чи Нью-Йорка (оскільки події не знайдено, додаток не може знати, що це сталося в Сідні, так що він не може автоматично вибрати правильний часовий пояс).

Який хороший спосіб запитати у користувача часову позначку, яка може містити часовий пояс?

Друге питання - як відобразити результати. Якщо командам з усього світу потрібно обговорити подію (і знайти пов’язані з нею події, подумайте про зловмисну ​​атаку, яка спрямована відразу на кілька сайтів по всьому світу).

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

Примітка. Будь ласка, зосередьтеся на зручності використання вимоги. Я можу сам розібратися у зіставленні бази даних. Наразі я не впевнений у потоці роботи. Він повинен запитати / подавати необхідну інформацію не нав'язливо / інтуїтивно. Якщо можете, дайте посилання на існуючий веб-додаток, який вже вирішує це.


5
Переповнення стека вирішує це, ставлячи все в UTC. Не завжди зручно, але, безумовно, однозначно, не складно втілити, і працює.
Ри-

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

3
Що робити, якщо одна із залучених країн приймає законодавство, яке змінює місцевий час після запланованої події, але до того, як подія відбудеться? Як система повинна це впоратися? en.wikipedia.org/wiki/…
Джуліус Мюсо

1
Цей тип класичного питання про часовий пояс настільки побитий протягом десятиліть в Інтернеті та в друкованому вигляді, я здивований, коли бачу такий живий відгук і прихильність цього питання!
BenSwayne

2
Я додаю додатковий момент складності, вказуючи на очевидне, а саме те, що більшість країн Західного світу змінює часові пояси двічі на рік ("літній час"), і що правила, коли це відбувається, не є рівномірними в усьому світі та не обов'язково тривіальними, алгоритмічно кажучи?
fr13d

Відповіді:


98

Проблема зберігання часових позначок проста: зберігайте їх у UTC.

Щодо їх відображення, було б доцільно прийняти налаштування часового поясу пристрою та використовувати його як поточний часовий пояс. З цього приводу слід поруч із полем "Введення часу" випадати часовий пояс, який за замовчуванням відповідає поточному часовому поясу пристрою, щоб користувач міг змінити його за потреби.

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

Насправді, ще краще було б зберегти часовий пояс, на який було встановлено пристрій під час першого запуску програми, а потім побачити, чи зміниться він коли-небудь. Якщо це все-таки зміниться, користувач, ймовірно, мандрівник і, ймовірно, виграє від випадання часового поясу. В іншому випадку просто не показуйте часовий пояс пристрою, що випадає та за замовчуванням (оскільки користувачеві про них не потрібно знати). У будь-якому випадку в додатку є налаштування, яке дозволяє користувачеві вручну показувати / приховувати спадне місце часового поясу.


Підсумовуючи сказане:

  • Під час першого запуску збережіть, на який часовий пояс встановлено пристрій.
  • Використовуйте цей часовий пояс як часовий пояс за замовчуванням. Завжди вважайте, що часовий пояс.
  • Якщо пристрій перемикає часові зони, додайте спадне меню, щоб вибрати, у якому часовому поясі відбувається подія, дефолт до власного часового поясу пристрою.
  • Додайте опцію для відображення / приховування цього спаду часового поясу вручну.
  • Завжди зберігайте часові позначки в UTC.

Що ми маємо на увазі під "часовим поясом" Це здається неоднозначно використаним. Це виглядає як посилання: en.wikipedia.org/wiki/Tz_database З того, що я можу сказати, "часовий пояс" - це "Площа / місце розташування", наприклад "Америка / Нью-Йорк". Це здається географічним, що чудово, тому що, наприклад, America / Los_Angeles означає BSTH PST та PDT залежно від того, чи працює земна куля в літній час. І якщо це так, питання полягає в тому, як ми враховуємо щорічні зміни в зміщенні UTC за зони? Крім того, що ми називаємо тими оцінками, оскільки вони географічно не є "зонами"?
iJames

Це чудова відповідь. Чи є найкраща практика щодо збереження інформації про часовий пояс? Наприклад - який з них буде кращим - "PST" або "America / Pacific"? Як я легко зможу конвертувати часову позначку в UTC у захоплений часовий пояс користувача? Будь-які найкращі практики щодо цього були б вдячні.
Паттебуг

27

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

Щодо зберігання дат, UTC - це шлях. Перетворити на UTC і вставити його в базу даних. Під час пошуку просто перетворіть час у встановлений для користувача часовий пояс.

Мені довелося вирішити подібний випадок використання, коли персоналізовані сповіщення, такі як "З Новим роком", можна було надсилати всім користувачам веб-програми. Оскільки користувачі розповсюджуються по всьому світу, нам потрібно було відображати сповіщення відповідно до часового поясу. Зберігання часової позначки в UTC чудово відповідало нашому призначенню, без ікони.

У вашому випадку використання, якщо ви не зберігаєте часовий пояс користувача десь, ви ніколи не зможете точно повернути результати пошуку, не вимагаючи введення користувача, якщо тільки ви не почнете використовувати якесь визначення місця розташування, як gmaps, але це не так " t надійний. Тому вам потрібно буде щоразу запитувати часовий пояс, щоб переконатися, що користувач знає, що він вводить на веб-сайті.

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

Сподіваюся, це допомагає! :)


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

Це чудова відповідь. Чи є найкраща практика щодо збереження інформації про часовий пояс? Наприклад - який з них буде кращим - "PST" або "America / Pacific"? Як я легко зможу конвертувати часову позначку в UTC у захоплений часовий пояс користувача? Будь-які найкращі практики щодо цього були б вдячні.
Паттебуг

11
  1. UTC Не ускладнювати.

  2. Використовуйте часовий пояс, найбільш відповідний користувачеві.

    Якщо ви знаєте, що користувач збирається заїхати до Сіднея або поїхати на цю подію, тоді вони будуть думати у тому часовому поясі, коли організувати транспорт до події. Те, що вони зараз перебувають у Нью-Йорку, значною мірою не має значення. І звичайно, якщо ваш додаток показує дати в різних часових поясах, він завжди повинен показувати часовий пояс поруч із датою, наприклад, 09:00 EST .

    Якщо ваш інтерфейс занадто не захаращений, ви можете відображати дати у часовому поясі події та локальному часовому поясі, наприклад, 2012-06-13 09:00 EST (2012-06-12 19:00 EDT) .

    Я заперечую, що пошук - це аналогічна проблема, з однією застережкою: ми можемо терпіти помилкові позитиви (отримуючи результат, якого ми не очікували), але ми не можемо витримати помилкових негативів (не отримуючи результату, якого ми очікували).

    Знову я б зосередився на пошуку найбільш релевантного часового поясу для користувача (наприклад, часовий пояс події) і надав цим результатам пріоритет у результатах пошуку, але ви також можете повернути події, які відповідають іншим часовим поясам, що стосуються користувача (наприклад, місцевий час). Якщо ви це зробите, вам слід показати дату події у відповідному часовому поясі, особливо якщо ви виділите текст, що відповідає.


7

Тут я даю пропозиції щодо найкращої зручності використання, не заважаючи багато про можливість реалізації.
1. Для першого випуску зберігання подій у db всі погодились би зберегти його в UTC

2. Щоб забезпечити найкращий досвід користувача, збережіть історію часового поясу користувача. Якщо ви зможете зберегти мітку часу зміни часового поясу, ще краще. Це дасть нам змогу надати користувачеві свободу запиту, не чітко визначаючи часовий пояс кожного разу.

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

3.Який хороший спосіб запитати у користувача часову позначку, яка може містити часовий пояс?

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

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

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

Ці пропозиції даються з наміром, що користувачеві не потрібно робити жодних обчислень у свій місцевий час, але в той же час він повинен мати можливість спілкуватися з іншими користувачами у бажаному часовому поясі.


2
+1 Це дуже цікава ідея, оскільки я знаю, що користувач входив у подію о 9:00 у Сіднеї, тому коли той самий користувач шукає час (без чіткого часового поясу), я повинен припустити, що він означає "там, де я був той час »
Аарон Дігулла

4

Гаразд, у мене інший підхід, ніж інші:

По-перше, я взяв на озброєння кілька речей.

Людина, яка перераховує подію, має смартфон (якщо це браузер, я не повинен робити цих припущень) з:

  1. GPS

  2. Можливість HTML5

  3. Можливість Javascript

Як слід зберігати позначки часу в базі даних?

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

Крок 1. Використовуйте геолокацію користувача за допомогою API Geolocation

    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, як API Yahoo (використовуйте прапор R, щоб Latitude перетворився на Timezone) для отримання часового поясу користувачів.

=> Часовий пояс користувачів визначається без введення користувача (я використовую це, тому що ви не можете просто припустити, що користувач знає часовий пояс місця, в якому він живе, я знав свій часовий пояс лише через кілька місяців або щось там: P, досить німий! )

У таблиці кожна подія має Timezone, Eventі тому може також CityName Потім створити ще одну таблицю бази даних з класифікацією , заснованої на CityNameс. Тож тут у користувача буде два колонки

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

Для інтерфейсу користувача

=> використовувати API Google Calendar або деякі API календаря

Пов'язані читання:

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

  2. Пошук часових поясів із широти

Я знаю це лише про те, щоб показати якусь ідею, як вирішити цю проблему. Але подивіться, наскільки точним і легким він стає для користувачів, коли часова зона визначається за допомогою API пристроїв

Сподіваюся, це допомагає!


4
Досить легко знайти чийсь часовий пояс без геолокації. new Date().getTimezoneOffset()передає його на хвилини за UTC.
Ри-

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

Так? Час буде однаковим в обох місцях, тому немає жодних проблем. -1
Ри-

@minitech, ви можете побачити це посилання, чому я рекомендую використовувати api пристрою, ніж інші методи. webdirections.org/sotmw2011
Удай

2
Гаразд, але проблема тут не в тому, щоб отримати місто користувача. Йдеться лише про те, щоб отримати часовий пояс. Використання API геолокації, який працює не в кожному браузері / комп’ютері, а потім перенаправлення на API календаря - це поганий спосіб отримати часовий пояс користувача, коли він доступний в одному рядку коду.
Ри-

2

Для цього конкретного випадку , я б зберігати як місцеве і UTC час. UTC є дещо основним і використовується для синхронізації та перетворення часу в поточний часовий пояс. Місцевий використовується для пошуку та додаткової інформації, наприклад:

У вас зустріч:

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.