#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.