Путаница в часовых поясах с использованием WCF

#c# #wcf #timezone

#c# #wcf #Часовой пояс

Вопрос:

У меня система SaaS с несколькими клиентами по всему миру. Однако каждый клиент находится только в одном часовом поясе. Связь между клиентом и моим центральным сервером осуществляется с использованием WCF.

Теперь в системе есть аспект планирования, и время должно храниться в терминах местного времени. Но я обнаружил, что когда я отправляю класс, помеченный DataContract атрибутом, имеющим DataMember свойство type DateTime , через интерфейс WCF, система становится вдвое умнее и переводит время в серверное. OTOH, если я передаю значение DateTime непосредственно через интерфейс WCF в качестве параметра, время передается дословно, как время клиента.

Это вызывает у меня много головной боли. Есть ли что-нибудь, что я могу где-нибудь настроить, чтобы служба WCF не переводила время в локальное (серверное) время?

РЕДАКТИРОВАТЬ: Ну, я не знаю, что я сделал, но я работал над некоторыми связанными вещами, и проблема, похоже, просто исчезла! Итак, я хотел бы попробовать ваши ответы, но на самом деле я не могу воспроизвести свою собственную проблему сейчас… Если бы у меня было время для академических упражнений, я бы посмотрел глубже, но прямо сейчас, если это не сломано…

Комментарии:

1. Привет, Шауль, я сталкиваюсь с той же проблемой с часовым поясом, что и у вас ранее. не могли бы вы рассказать мне, как вы это решили. это будет очень полезно как для меня, так и для других. Я бы не хотел менять код, однако изменения в конфигурации меня устраивают.

2. @Bravo — смотрите принятый ответ: используйте время UTC

Ответ №1:

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

Комментарии:

1. 1 Я согласен на 100%. Не усложняйте жизнь, сохраняя разные часовые пояса внутри. Как вы собираетесь учитывать такие вещи, как переход на летнее время? Что произойдет, если пользователь изменит часовые пояса? Список можно продолжить. Я считаю, что utc => локальное преобразование является детализацией на уровне просмотра. Просто используйте UTC.

2. Я думаю, вы оба меня неправильно поняли: я не хочу сохранять разные часовые пояса внутри; WCF автоматически преобразовывал их, и в этом была проблема! Но, как я уже сказал в своей правке, я, похоже, все равно непреднамеренно исправил проблему…

3. «У WCF нет никакой возможности автоматически преобразовывать значения времени во время UTC». Верно, но в зависимости от сериализации и прочего, действительно происходят странные вещи.

Ответ №2:

Я знаю, что это старый вопрос, но если кому-то нужно, вот он:

Я полагаю, вы делаете DateTime.Now на стороне клиента. Вместо использования этого оператора используйте :

 DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified)
  

Он получает локальную дату и время клиента, и это не изменится на сервере.

Комментарии:

1. К вашему сведению, я пробовал это (IIS 7.5, .Net 4), но независимо от того, установил ли я DateTimeKind явно перед возвратом моего значения даты, Fiddler, тем не менее, показывает, что я получаю часовой пояс в возвращаемом сериализованном JSON: «/Date(1338177600000-0400) /».

2. Использование . Неопределенность может рассматриваться как халатность, вместо этого используйте DateTimeOffset — см. blogs.msdn.com/b/davidrickard/archive/2012/04/07 /…

Ответ №3:

Попробуйте использовать объекты DateTimeOffset — смещение часового пояса также сохраняется, и если время переведено, вы сможете перевести его обратно. Вам нужен .NET 3.5 или более поздняя версия.

Вам придется немного изменить свой код, поскольку DateTimeOffset и DateTime не могут быть сопоставлены друг с другом (их можно преобразовать).

Вам не обязательно изменять вызовы хранимых процедур, но если вы обнаружите необходимость, DateTimeOffset также существует в SQL Server.