Melhores práticas para DateTime serialização .NET 3.5
-
09-06-2019 - |
Pergunta
A cerca de 4 anos atrás, eu segui este Artigo do MSDN para DateTime uso de melhores práticas para a construção de uma .Líquido cliente .Net 1.1 e ASMX (serviços web com SQL 2000 server como o back-end).Ainda me lembro da serialização problemas que eu tinha com data / hora e o teste de esforço necessário para que os servidores em diferentes fusos horários.
Minhas perguntas é este:Existe um semelhante documento melhores práticas para algumas das novas tecnologias, como o WCF e SQL server 2008, especialmente com a adição de novos tipos datetime para o armazenamento de fuso horário ciente de informações.
Este é o ambiente:
- O SQL server de 2008, no Horário do Pacífico.
- Camada de Serviços Web em um fuso horário diferente.
- Os clientes possam usar .Net 2.0 ou .Net 3.5 em fusos horários diferentes.Se torna mais fácil, podemos forçar todos a atualizar .Net 3.5.:)
Qualquer boas sugestões de melhores práticas para os tipos de dados a serem usados em cada camada?
Solução
Eu acho que a melhor maneira de fazer isso é sempre passar o objeto como UTC e converter para a hora local nos clientes.Ao fazer isso, há um ponto de referência comum para todos os clientes.
Para converter para UTC, chamada ToUniversalTime sobre o objeto DateTime.Em seguida, nos clientes, chamada ToLocalTime para obtê-lo no seu fuso horário atual.
Outras dicas
Um grande problema é que o WCF serialização não suporta xs:Date.Este é um grande problema, como se tudo que você quer é uma data, você não deve ser obrigado a estar preocupado com os fusos horários.Os seguintes ligar problema discute alguns dos problemas: http://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=349215
Se você deseja representar um ponto no tempo, de forma inequívoca, i.é.não apenas a parte da data, você pode usar o DateTimeOffset classe, se você tiver .NET 3.5 em ambos cliente e servidor.Ou para a interoperabilidade, sempre passar valores de data/hora em UTC.
UTC/GMT seria consistente em ambiente distribuído.
Uma coisa importante é que especifique o datetimeKind depois de preencher o seu DateTime propriedade com o valor a partir do banco de dados.
dateTimeValueUtcKind = DateTime.SpecifyKind(dateTimeValue, DateTimeKind.Utc);
Enquanto sua camada de serviços web e a camada de cliente utilizar .LÍQUIDO do tipo DateTime, deve serializar e desserializar corretamente como um SABÃO-padrão local de data/hora c/ informações de Fuso horário, tais como:
2008-09-15T13:14:36.9502109-05:00
Se você absolutamente, positivamente, deve saber o fuso horário próprio (i.e.acima poderia ser a Hora Padrão do Leste ou Hora de Verão Central), você precisa criar o seu próprio tipo de dados que expõe essas peças como essas:
[Serializable]
public sealed class MyDateTime
{
public MyDateTime()
{
this.Now = DateTime.Now;
this.IsDaylightSavingTime = this.Now.IsDaylightSavingTime();
this.TimeZone = this.IsDaylightSavingTime
? System.TimeZone.CurrentTimeZone.DaylightName
: System.TimeZone.CurrentTimeZone.StandardName;
}
public DateTime Now
{
get;
set;
}
public string TimeZone
{
get;
set;
}
public bool IsDaylightSavingTime
{
get;
set;
}
}
em seguida, a sua resposta seria:
<Now>2008-09-15T13:34:08.0039447-05:00</Now>
<TimeZone>Central Daylight Time</TimeZone>
<IsDaylightSavingTime>true</IsDaylightSavingTime>
Eu tinha boa sorte com apenas manter o tipo de dados DateTime e sempre armazenando-os como GMT.Em cada camada, eu ajustar o GMT valor para o valor local para a camada.