Hace unos 4 años, seguí esto artículo de MSDN para las mejores prácticas de uso de DateTime para construir un cliente .Net en .Net 1.1 y servicios web ASMX (con el servidor SQL 2000 como back-end). Todavía recuerdo los problemas de serialización que tuve con DateTime y el esfuerzo de prueba que tomó para servidores en diferentes zonas horarias.
Mi pregunta es esta: ¿Existe un documento similar de mejores prácticas para algunas de las nuevas tecnologías como WCF y SQL Server 2008, especialmente con la adición de nuevos tipos de fecha y hora para almacenar información de zona horaria.
Este es el medio ambiente:
¿Alguna buena sugerencia/mejores prácticas para los tipos de datos que se utilizarán en cada capa?
Creo que la mejor manera de hacerlo es pasar siempre el objeto como UTC y convertirlo a la hora local en los clientes. Al hacerlo, hay un punto de referencia común para todos los clientes.
Para convertir a UTC, llame a ToUniversalTime en el objeto DateTime. Luego, en los clientes, llame a ToLocalTime para obtenerlo en su zona horaria actual.
Un gran problema es que la serialización WCF no es compatible con xs: Date. Este es un gran problema, ya que si todo lo que desea es una cita, no debería verse obligado a preocuparse por las zonas horarias. El siguiente problema de conexión analiza algunos de los problemas: http://connect.Microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=349215
Si desea representar un punto en el tiempo sin ambigüedades, es decir, no solo la parte de la fecha, puede usar la clase DateTimeOffset si tiene .NET 3.5 tanto en el cliente como en el servidor. O para la interoperabilidad, siempre pase los valores de fecha/hora como UTC.
UTC/GMT sería consistente en un entorno distribuido.
Una cosa importante es que especifique datetimeKind después de completar su propiedad DateTime con el valor de la base de datos.
dateTimeValueUtcKind = DateTime.SpecifyKind(dateTimeValue, DateTimeKind.Utc);
Siempre que su capa de servicios web y la capa de cliente utilicen el tipo .NET DateTime, debe serializarse y deserializarse correctamente como una fecha/hora local estándar SOAP con información de zona horaria como:
2008-09-15T13: 14: 36.9502109-05: 00
Si absolutamente, debe conocer positivamente la zona horaria en sí (es decir, lo anterior podría ser la hora estándar del este o la hora de verano central), debe crear su propio tipo de datos que exponga esas piezas como tales:
[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;
}
}
entonces su respuesta se vería así:
<Now>2008-09-15T13:34:08.0039447-05:00</Now>
<TimeZone>Central Daylight Time</TimeZone>
<IsDaylightSavingTime>true</IsDaylightSavingTime>
Tuve buena suerte con solo mantener el tipo de datos DateTime y siempre almacenarlo como GMT. En cada capa, ajustaría el valor GMT al valor local para la capa.