2013-08-20 4 views
3

Мне интересно, как представить дату (без элемента времени) пользователям из разных часовых поясов. Предположим, что дата хранится в некоторой базе данных на каком-то сервере, который работает в определенном часовом поясе (например, UTC + 6), а сервер приложений работает на том же компьютере (или, по крайней мере, в том же часовом поясе). Приложение должно обрабатывать два типа временных значений: A/DateTime (например, 2013-08-20 08:00 UTC) и B/Дата (например, 2013-08-20).Как представить дату (без элемента времени) пользователям из разных часовых поясов?

A/DateTime прост в обращении, поскольку он представляет собой определенный момент в истории. Например, Moon Landing. Он хранится в UTC в базе данных и всякий раз, когда он представляется клиенту, он перемещается в свой часовой пояс, чтобы он вписывался в его реальность. Так 2013-08-20 08:00 UTC = 2013-08-20 14:00 UTC + 6 = 2013-08-19 22:00 UTC-10. Каждый клиент смотрит на тот же момент времени = одно и то же событие с его точки зрения, и все гладко.

B/Date = ПРОБЛЕМА. Этот тип временного значения представляет собой определенный день в истории. Поскольку у него нет элемента времени, его нельзя переместить в разные часовые пояса. Казалось бы, легко хранить даты с нулевым компонентом времени как 2013-08-20 00:00 UTC и представлять его без компонента времени для пользователей. Но после смещения это приведет к 2013-08-19 из часовых поясов UTC-x, и это неправильно, потому что мы действительно не знаем, в какой части мира этот момент в истории считается вчера и где он до сих пор. На самом деле на некоторых планетах есть три разных даты (http://en.wikipedia.org/wiki/International_Date_Line).

Хорошим примером проблемы является дата выставления счета. Когда вы выставляете счет-фактуру с датой 2013-08-20 в часовом поясе UTC + 6 и храните ее на сервере, расположенном в UTC, когда кто-то из Китая заплатит? Это 2013-08-19 на сервере, основанном на UTC, или это еще 2013-08-20?

Чтобы сформулировать вопрос:

Как должна быть дата без времени элемента хранится и обрабатывается как позволяют обслуживать его клиентов из нескольких часовых поясов (в том числе более 12 часов разницы)? Должен ли он быть перенесен? Должна ли она оставаться на ту же дату? Как вы справляетесь с этим сценарием в своих проектах?

Большое спасибо за чтение до этого момента. Любые ссылки или идеи приветствуются. Только соответствующий материал, который я смог достичь, был упомянутой ранее статьей wiki, но, честно говоря, я не уверен, есть ли ответ на мой вопрос. Большинство статей связаны с сдвигом по времени, но эта часть хорошо справляется с этой точки зрения.

P.S. Сервер приложений написан на Java, поэтому я помечаю этот вопрос Java, связанный с поддержкой конкретных решений Java, если они есть.

+0

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

ответ

2

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

В Java, вы должны использовать библиотеку Joda Time для этих проблем. Это поможет вам отделить понятия, о которых вы говорите.

  • Первая концепция, которую вы определили, называется Instant в Joda Time. При привязке к часовому поясу он называется DateTime.

  • Вторая концепция в эпоху Джоды называется LocalDate.

  • Вы также определили тип DateMidnight - по моему соглашению, вероятно, не будут работать в соответствии с вашими конкретными потребностями.

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

Как отметил Дункан в комментариях - вам сложно напрямую сообщить, что вам следует делать, потому что разные компании имеют разные требования в этом отношении. Но вот некоторые разные подходы:

  • можно привязать к LocalDate к концу дня в часовом поясе клиента, что означает различный момент для каждого клиента для вашей компании.

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

  • У вас может быть политика компании, которую рабочий день задает UTC.

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

Последний вопрос - вы всегда должны убедиться, что вашему коду не важно, что такое часовой пояс сервера. Вы можете легко развернуть сервер, имеющий определенный часовой пояс, и вы не хотите, чтобы он что-то сломал. Умное использование типов UTC или Date/Time/Offset решит это для определенных моментов времени. Но так как LocalDate не является точным моментом во времени - вы должны быть осторожны, чтобы получить его от часового пояса в вашей прикладной логике. Не просто спросите сервер «сейчас» и предположите, что это правильная зона.

Смежные вопросы