viernes, 4 de enero de 2013

Importancia DateTime.SpecifyKind trabajando con nullable<DateTime> en escenarios de intercambio XML

Al enviar/recibir información entre varias plataformas en formato Xml ya sea vía soap o similares tenemos que considerar la importancia de especificar bien la zona horaria al trabajar con campos DateTime en el Xml para evitar situaciones comprometidas.

Por defecto al definir un campo de tipo xs:Datetime en un modelo xsd aceptará un valor de Fecha y Hora con o sin especificar la zona horaria. Para especificar la zona horaria tendríamos que concatenar una "Z" (defecto, UTC) o concatenar al final +/- HH:mm para indicarle que desvío queremos que se aplique en la fecha respecto a GMT.

Resumiendo no hay modo de obligar a través de una definición tipo xsd a especificar la zona horaria en los campos de tipo fecha. Tal vez usando el atributo pattern de la especificación para DateTime se podría llegar a hacer algo pero no lo he probado y seguramente herramientas de generación de código como svutil o axis no reconocerían esta restricción con lo tampoco ganaríamos mucho.

A continuación veremos un caso curioso relacionado con la zona horaria que podría darse si estamos trabajando en una plataforma .NET c#:
DateTime fechaActual = DateTime.Now;
DateTime? fechaDesde = null;

fechaDesde = fechaActual.AddDays(-1);
Si nos fijamos el campo fechaDesde está definido como nullable.
<s:Envelope>
<s:Body>
<request>
<a:fechaDesde>2012-12-28T09:20:12</a:fechaDesde>
<a:fechaHasta>2013-01-03T11:59:55.0938142+01:00</a:fechaHasta>
</request>
</s:Body>
</s:Envelope>
Al enviar esta información vía soap, en el campo fechaDesde no se ha concatenado el +01:00 de la zona horaria mientras en el campo hasta si lo está. Esto podría originar que el receptor del mensaje tome el formato UTC tomando como valor 1 hora menos en este caso. La clase DateTime de .NET tiene una propiedad Kind que permite consultar la zona horaria del tipo, y por otro lado tenemos el método DateTime.SpecifyKind que permite especificar el tipo de zona horaria que queremos por defecto. En los tipos DateTime por defecto toma el valor "Local" que se corresponde al sistema operativo que esté ejecutando la aplicación pero en los tipos nullable está propiedad no se comporta del mismo modo por defecto al definir la instancia y hemos de asignarle mediante SpecifyKind el tipo de zona horaria que necesitamos. Veamos como hacerlo:
DateTime fechaActual = DateTime.Now;
DateTime? fechaDesde = null;

fechaDesde = DateTime.SpecifyKind(fechaActual.AddDays(-1), DateTimeKind.Local);
Con esto ya estaríamos especificando a nivel soap la zona horaria en el campo fecha desde como vemos abajo.
<s:Envelope>
<s:Body>
<request>
<a:fechaDesde>2012-12-28T09:20:12+01:00</a:fechaDesde>
<a:fechaHasta>2013-01-03T11:59:55.0938142+01:00</a:fechaHasta>
</request>
</s:Body>
</s:Envelope>
Hasta aquí el artículo de hoy, os recuerdo que podéis seguir areaTIC en las redes sociales o vía RSS!


No hay comentarios:

Publicar un comentario