2016-10-11 6 views
3

В нашем приложении мы сохраняем UTC DateTime в DataBase. Клиент (javascript) отправляет дату-время в Local TimeZone и на уровне контроллера мы конвертируем его в UTC, прежде чем сохранять дату в базе данных.UTC смещение от сервера к клиенту

Оба клиента и серверы находятся в разных часовых поясах.

мы извлечение даты из базы данных в формате UTC с помощью Entity Framework с

DateTime.SpecifyKind(_CreatedDate, DateTimeKind.Utc); 

Так мы должны снова преобразовать DateTime в локальный DateTime на контроллере или мы должны обрабатывать всю логику преобразования DateTime на клиенте.

ответ

4

При отправке DateTime экземпляров на сервер конвертация конвертация в UTC должна происходить как можно раньше. В этом случае клиентом и вашим клиентом является javascript, вы можете использовать метод toUTCString. Если вы используете momentjs, вы можете использовать utc.

При получении DateTime экземпляров с сервера конвертация переход на местное время должен происходить как можно позже. Убедитесь, что сохраненные даты/даты получены в формате UTC при их создании. Опять же, именно клиент должен преобразовывать их в локальный экземпляр даты.

Наконец, отправьте все экземпляры datetime между клиентом и сервером, используя формат ISO8601. Momentjs, объект даты javascript, json.net все это могут сделать. Это гарантирует, что ничего не потеряно и не будут введены какие-либо культурные специфические ошибки.

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

Что касается сохранения, вы можете использовать либо тип DateTime, либо DateTime со смещением (имена истинных типов зависят от используемых вами RDBM). Какой из них выбрать, зависит от того, важно ли знать смещение от utc в момент его сохранения. До сих пор мне не приходилось это делать, но, возможно, это важно для вас. Он не влияет на фактический момент времени, так как DateTime должен представлять точку UTC во времени, а смещение должно представлять локальное время со смещением, чтобы вернуться к точке UTC во времени.

+0

. Итак, вы в основном говорите, что все преобразования с локального на UTC или UTC на локальный должны выполняться только на стороне клиента –

+1

@vikas - да, клиент/браузер должен всегда знать свой часовой пояс, поэтому имеет смысл переложить эту ответственность на него. Например: просто вызов toLocal в экземпляре momentjs преобразует время utc utc в правильное datetime в этом языке (который зарегистрирован на машине браузеров). Когда клиент отправляет даты и время, как UTC также имеет смысл по той же причине. – Igor

1

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

Когда вы отправляете datetimeoffset с сервера на клиент, вы можете выполнить преобразование на стороне клиента. Я не думаю, что кто-нибудь будет утверждать, что MomentJS Timezone - лучшая библиотека для этого. Посмотрите на него и сделайте снимок.

http://momentjs.com/timezone/

Конкретизируя DateTimeOffset

DateTimeOffset еще один тип данных, как DateTime кроме DateTimeOffset добавляет час смещение для определения часового пояса. Например, допустим, вы находитесь в Центральном часовом поясе, и хотите сохранить время 08:00 am. Ну, в Datetimeoffset было бы что-то вроде 08:00:00:00 -04:00, заявив, что смещение было -4 (центральный часовой пояс). Это облегчает работу, потому что вам не нужно делать какую-либо математику в своей голове, когда вы читаете ее, и вам действительно не нужно делать никаких конверсий (пусть MomentJS сделает это за вас). Когда вы прочтете это, вы всегда будете знать, что «О, это было 08:00 для тех, кто спас время, и похоже, что они сохранили его в центральном часовом поясе».

+0

Вы можете подробно рассказать о 'datetimeoffset' в этом контексте, потому что я не понимаю, как« datatimeoffest »поможет мне. –

+0

@vikas Я только что пересмотрел ответ – James

+0

@vikas Если вы используете DateTimeOffset, как я уже сказал, когда вы отправляете значение datetimeoffset клиенту, оно будет иметь значение смещения. Вы используете это значение смещения, чтобы узнать, в какой временной зоне время было сохранено в – James

1

Так как это довольно относительный , когда является «правильным» временем для преобразования.

Единственное абсолютное правило, которое я считаю действительным, - это одно.

UTC время только Реальные значимые данные

Любое другое преобразование в любой часовой пояс является просто «Display» для меня

Так следовать тем же правилам, как вы бы с остальная часть ваших данных.

Как преобразование булева в флажок в представлении. Или отправьте это значение флажка на логическое значение на сервер.

И это Скорейшее она Достигает или ЛистьяUI.

+0

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

+1

Вы мгновенно конвертируете свое время, когда вы читаете его с помощью DateTime Picker, поэтому сравнения на стороне клиента выполняются также в формате UTC. Поскольку ваше значение оставило пользовательский интерфейс (например, сборщик), пришло время преобразовать его в utc. Оставить пользовательский интерфейс означает также прочитать его из сборщика и отправить его как значение функции javascript –