2015-05-12 2 views
3

Я собираюсь сходить с ума по поводу проблем с датой и в Интернете.Передача часового пояса в веб-ави звонок с момента с nodatime

У меня есть веб-сервер, размещенный в Центральном часовом поясе. Когда клиенты в Восточном часовом поясе пытаются и планируют элемент в течение определенного дня с помощью моего приложения, они передают значение (например) 3/14/2015. Когда мы передаем код обратно в нашу модель, которая отправляется в веб-api, мы сохраняем использование чего-то вроде кода ниже.

moment.utc($("#mydatepicker").val).hour(0).minute(0).second(0)).toISOString(); 

Это приводит к строке, как следующее:

2015-03-14T04:00:00.000Z 

Когда элемент преобразуется обратно на сервер в Web API, он превращается в

3/13/2015 11:00:00 PM 

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

Мне нужно знать, как отправить значение с момента, в веб-api предпочтительнее, как ZonedDateTime в часовом поясе клиента. Затем я могу преобразовать его в UTC для сохранения в БД.

Я видел что-то об использовании NodaTime.Serialization.JsonNet, но я не понимаю, как использовать его с Moment и передавать его взад и вперед по веб-интерфейсу api/ajax.

ответ

7

Мне нужно знать, как отправить значение с момента, в веб-api предпочтительнее, как ZonedDateTime в часовом поясе клиента. Затем я могу преобразовать его в UTC для сохранения в БД.

Если это то, что вы хотите, то:

  • В коде moment.js, используйте .format() вместо .toISOString(), который еще даст вам ISO8601 строку, но будет включать в себя локальное смещение вместо установить его в UTC.

  • В вашем коде ASP.Net определите свои значения как DateTimeOffset (или нода OffsetDateTime), а не DateTime.

Однако, я не думаю, что это на самом деле то, что вы хотите. Когда дело доходит до дат и времени, контекст очень важен. Здесь вы сказали, что выбираете дату с даты выбора. Когда вы это делаете - какое время выбирает пользователь? В большинстве случаев они не выбирают время - они просто выбирают дату. Но поскольку объект JavaScript Date действительно является объектом «дата + время», он назначает полночь в качестве времени по умолчанию.Момент в этом отношении не лучше.

Действительно, преобразование в UTC не имеет логического смысла, когда вы просто говорите о дате календаря. Строковое значение, которое вы возможно должно быть отправлено по проводу, должно быть просто целой датой, как в "2015-03-14". Полагаю, это то, с чего вы все-таки начинаете. Если нет, то сделайте moment.utc(yourvalue).format("YYYY-MM-DD"), чтобы получить его. (Использование UTC здесь - это всего лишь способ избежать локальных часовых поясов, например, полночь, не существующая в Бразилии в день весеннего перерыва.)

Это соответствует типу NodaTime LocalDate в вашем коде .NET. Если вы не использовали Noda Time, вы бы определили тип как DateTime и просто проигнорировали часть времени. В вашей базе данных, если есть доступный тип даты, используйте его. Например, SQL Server имеет тип date.

Я также призываю вас посмотреть мой курс Pluralsight, Date and Time Fundamentals - который охватывает многие из этих проблем.

Что касается использования NodaTime.Serialization.JsonNet в WebAPI (так что вы можете использовать LocalDate непосредственно), в вашем WebApiConfig.cs файл, проволока его следующим образом:

config.Formatters.JsonFormatter.SerializerSettings 
       .ConfigureForNodaTime(DateTimeZoneProviders.Tzdb); 

Тогда это должно работать.

+0

Казалось, это сработало. Я изменил результат даты на строку даты, и все, похоже, работают. Я все еще делаю логическую серверную сторону, но все выглядит нормально. Я делаю дополнительную логику, чтобы убедиться, что я сохраняю значения во время моей франшизы (их TZ хранится в БД), а затем конвертируется в UTC для хранения БД. Я должен обучать своих пользователей тем, что если вы установите значение для Midnight franch. время, и они на час опережают вас, когда вы просматриваете результат локально, момент покажет его в свое местное время, поэтому он будет на час меньше, чем для франшизы. Заставляет меня опрокинуться. Проведет курс. – SpaceCowboy74

1

Я бы начал с отправки всех дат и времени на сервер в виде UTC. Если вы сохраняете время UTC только тогда, вы должны иметь возможность показать правильное время, когда что-то запланировано на стороне клиента.

Когда вы создаете свой момент на стороне клиента, вы сначала запускаете его .toDate() перед отправкой его на сервер? Какой код вы используете на стороне сервера? Это .Net WebApi?

+0

Код, который вы видите выше, точно с моей стороны клиента. Я отправляю и получаю все в utc формате. Однако я не делаю toDate. Это .NET WebApi на стороне сервера. Случается, что время в UTC устанавливается в полночь, но сервер видит его на час раньше (11 часов дня предыдущего дня), потому что клиент находится в восточном направлении, а сервер находится в центре. – SpaceCowboy74

+0

ОК, я понимаю сейчас. На стороне клиента вы должны преобразовать свой момент(). ToDate(), чтобы сериализованный JSON, который вы отправляете на сервер, будет иметь правильный формат для вашего webapi. На сервере такое же правило все еще стоит, вы должны хранить в UTC, чтобы клиент мог потянуть время и правильно просмотреть его. Кажется, что вы делаете локальное изменение часового пояса даты раньше. Отображается ли на стороне сервера DateTime как дата UTC? –

+0

№ На стороне сервера, когда WebApi читает переменную (мы создаем объект с помощью аргумента '[FromBody] MyModel myModel' функции), он создает его как DateTimeKind.Local. Таким образом, полуночное восточное время рассматривается как 11 часов назад, когда создается как локальное. Я вижу, что кто-то помещает код в его изменение в Unspecified. Возможно, это вызывает проблему. – SpaceCowboy74