2016-02-16 2 views
2

Мы работаем над приложением IOS с использованием Azure Mobile Services от Microsoft. Веб-интерфейс GUI создает даты-время как поля DateTimeOffset, что отлично. Но когда у нас есть мобильная связь datetime в базе данных, затем читайте их из базы данных через Entity Framework, мы видим, что они настроены на UCT. (Мы видим то же самое, когда просматриваем записи в SSMS.)Почему Azure теряет информацию о часовом поясе в полях DateTimeOffset?

Я всегда был разочарован отсутствием поддержки часового пояса в стандартных типах времени и времени SQL, и я думал, что DateTimeOffset будет лучше. Но если бы я хотел, чтобы мои времена были в UTC, я бы сохранил их в UTC. Если пользователь вводит время как 3:00 AM, CST, я хочу знать, что он ввел CST. Мне так мало смысла конвертировать его в UTC и отбрасывать смещение, так как это предполагало, что 3:00 AM CST и 3:00 AM PDT были одинаковыми.

Есть ли какая-то конфигурация базы данных, которую я могу сделать, чтобы база данных Azure сохраняла даты в UTC?

ответ

2

Проблема заключается в том, что в какой-то момент в Azure Mobile Services свойство преобразуется в объект JavaScript Date, который не может сохранить смещение.

Есть несколько сообщений в блоге, описывающее этот вопрос, а также возможные пути решения проблемы:

По существу, они оба принимают один и тот же подход расщепления выведите смещение в отдельное поле. Тем не менее, внимательно глядя на них, они оба делают решающую ошибку:

dto.DateTime.ToUniversalTime() 

Если на самом деле быть:

dto.UtcDateTime 

DateTime из DateTimeOffset всегда будет иметь DateTimeKind.Unspecified, и, таким образом, ToUniversalTime будет считать, что источник local, вместо использования смещения DTO.

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

+0

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

+0

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

+0

Не совсем осуществимо - это взаимодействие между мобильным приложением IOS и базой данных Azure, которая теряет смещение. –

0

Мы используем бэкэнд Node.js и заметили то же самое с DATETIMEOFFSET s, прочитанным из нашей базы данных SQL Server, возвращаемой в UTC независимо от смещения. Другой альтернативой является преобразование DATETIMEOFFSET на уровне запроса, чтобы оно выводилось как строка с информацией о часовом поясе. Следующее преобразует поле DATETIMEOFFSET(0) в формат ISO8601; Однако, другие возможные стили могут быть использованы в качестве документированной here:

SELECT CONVERT(VARCHAR(33), [StartDate], 126) AS [StartDate] FROM [Products];

Новый выход теперь: "2016-05-26T00:00:00-06:00" вместо "2016-05-26T06:00:00+00:00"

Конечно, это означает, что клиент должен сериализовать строки в их соответствующие формат. В iOS библиотеку ISO8601 можно использовать для считывания вывода либо как NSDateComponents, либо NSDate.

Одним из преимуществ такого подхода является то, что любые проверки на уровне базы данных или триггеры могут проводить сопоставление дат с использованием DATETIMEOFFSET вместо того, чтобы пытаться учесть отдельный столбец смещения с базовым DATETIME.

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