Plugins y fechas en Dynamics 365

Plugins y fechas en Dynamics 365

22 octubre, 2020 eromerof 0 Etiquetas: ,

¿Qué ocurre? ¿Por qué un proceso o un plugin me devuelve el día anterior cuando le pregunto una fecha en dynamics 365? ¿Cuántas veces te has preguntado esto sin mucho éxito?

Ya escribí un post anterior donde explicaba todos los comportamientos de la fecha y que te recomiendo revisar porque quizás te ayude. Es muy posible que hayas tenido algunos problemas con las fechas y hoy voy a darte estos consejos y te recomiendo que inviertas tiempo en probarlo porque será cuando lo veas más claro:

1.- Revisa el comportamiento del campo

Debemos de tener en cuenta el comportamiento en que se encuentra nuestro campo del CDS: local del usuario, sólo fecha o independiente de la zona horaria. Puedes consultar más detalles de estos comportamientos aquí.

Recuerda: La API de Dynamics 365 por defecto SIEMPRE tratará de devolverte la hora en UTC.

2.- En plugin o Custom Workflow Activity.. la hora no es la misma

Y así es, recuerda que cuando ejecutas un plugin en Dynamics 365 se está ejecutando en un servidor de Microsoft y, por lo tanto, la zona horaria del servidor será en UTC (al menos aquí en Europa, no he probado con EEUU o Sudamérica). Por lo tanto cuando realicemos un .tolocaltime() en el servidor no servirá de nada puesto que la zona horaria configurada en el servidor y la hora que nos devuelve Dynamics 365 es la misma.

3.- Convierte a tu zona horaria local desde el servidor de Dynamics 365 para comparar

Para esto lo que he hecho es una clase de extensión que me permite convertir fácilmente a la zona horaria de España (en este ejemplo). Sobre todo cuando trabajo con los distintos comportamientos de las fechas en Dynamics 365 es necesario este tipo de conversiones ya que, dos fechas las debo comparar siempre en la misma zona horaria (UTC con otra fecha en UTC…etc):

public static DateTime toMadridDateTime(this DateTime MyDate)
{
   return TimeZoneInfo.ConvertTimeFromUtc(MyDate.ToUniversalTime(),                     TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time"));
}

Romance Standard Time es la zona horaria designada para España pero puedes buscar aquí el resto de zona horaria para los distintos países. Recuerda: si conviertes una fecha con este método y vuelves a insertarlo en Dynamics 365 seguirá estando mal porque en realidad la fecha sigue siendo la misma, simplemente la estás viendo como si estuvieras en la zona horaria que has especificado. La fecha es la misma únicamente has cambiado la referencia.

4.- Convierte tu fecha a otra zona horaria

Para solucionar la problemática que he planteado en el anterior párrafo lo que debemos hacer es instanciar un nuevo objeto DateTime donde le indicamos la zona horaria en la que en realidad se encuentra. Esto también ocurre en escenarios donde utilizamos el comportamiento «Independiente de la zona horaria» ya que, cuando D365 nos devuelve el valor el DateTime se encuentra en UTC, sin embargo esto no puede ser así. Para solucionarlo añade esta clase a tu código:

public struct DateTimeWithZone
{
    private readonly DateTime utcDateTime;
    private readonly TimeZoneInfo timeZone;

 public DateTimeWithZone(DateTime dateTime, TimeZoneInfo timeZone)
 {
    var dateTimeUnspec = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified);
    utcDateTime = TimeZoneInfo.ConvertTimeToUtc(dateTimeUnspec, timeZone);
    this.timeZone = timeZone;
 }

 public DateTime UniversalTime { get { return utcDateTime; } }

 public TimeZoneInfo TimeZone { get { return timeZone; } }

 public DateTime LocalTime
 {
    get
    {
       return TimeZoneInfo.ConvertTime(utcDateTime, timeZone);
    }
 }
}

Invócalo del siguiente modo:

DateTimeWithZone Startdatezone = new DateTimeWithZone(StartDateTime_local, TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time"));

De este modo lograrás indicar a el código que esa hora en concreto que él cree que está en UTC, en realidad está en la zona horaria que le indiques.

5.- Suma o resta el offset correspondiente a la zona horaria

En España tenemos dos horarios: En invierno estamos en UTC+1 sin embargo en verano nos encontramos en UTC+2. Esto es un buen lío a la altura del fin del mundo del año 2000. Esto es un problema para los ajustes horarios y otro modo de poder solucionar las cosas es restando (o sumando) el offset de horas que tenemos. Yo he desarrollado este pequeño método y, de momento, me sigue funcionando:

private int CalculateHourDifference(DateTime DateInUTC)
{
    var DateInRomance = DateInUTC.toMadridDateTime();
    return DateInRomance.Hour - DateInUTC.Hour;
}

Este método nos devuelve la diferencia de horas entre una hora en UTC y su hora en la zona horaria específica. El método de extensión toMadridDateTime lo he mostrado un poco más arriba. De este modo para calcular la diferencia horaria puedo sumar o restar esta diferencia de horas a mi hora en UTC o local respectivamente.

Espero haberte ayudado aunque sea un poco y me alegraría mucho que me lo hicieras saber!

Leave a Reply:

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *