Imagino que en numerosas ocasiones te has encontrado con el siguiente problema: tu cliente te pide que incluyas la fecha de actualización del modelo semántico en un objeto visual. Hasta aquí todo perfecto 👏🏼, terminas tu informe y lo subes al servicio, ¡voilà! 😯 Pero la hora que ves no coincide con la que tenías en el Desktop. ¿Por qué ocurre esto?
Muy fácil, el servicio de Power BI es un servicio alojado en la nube, lo que significa que utiliza la fecha y hora del servidor en el que esté alojado, en este caso, usa UTC.
¿Entonces? ¿Cómo puedo ajustar la hora correctamente al país en el que me encuentro y a su horario si es verano o invierno?
En el caso de España hasta 2027 tenemos 2 cambios de hora al año, uno en marzo y otro en octubre.
Os pongo un ejemplo:
DateTime.AddZone(DateTime.FixedLocalNow(),2)
Vamos a ir desgranando la función:
DateTime.AddZone tal y como dice la documentación de Microsoft «Agrega información de zona horaria al valor dateTime
. La información de zona horaria incluye timezoneHours
y, opcionalmente timezoneMinutes
, que especifica el desplazamiento deseado a partir de la hora UTC.»
Sintaxis
DateTime.AddZone(dateTime as nullable datetime, timezoneHours as number, optional timezoneMinutes as nullable number) as nullable datetimezone
DateTime.FixedLocalNow dice la documentación que «Devuelve un valor datetime
establecido en la fecha y hora actuales según el sistema. El valor devuelto contiene información de la zona horaria que representa la zona horaria local. Este valor es fijo y no cambiará con las sucesivas llamadas, a diferencia de DateTimeZone.LocalNow, que puede devolver valores distintos durante la ejecución de una expresión.»
Sintaxis
DateTimeZone.FixedLocalNow() as datetimezone
El 2 en la función actúa como timezoneHours y varía en función de si estamos en horario de verano o invierno. Es decir, ahora mismo tenemos UTC + 2 porque nos encontramos en horario de verano pero en octubre pasará a ser UTC + 1 por el cambio de hora de invierno.
Entonces el problema que tenemos es que manualmente tendríamos que cambiar ese 2 por un 1 y el año siguiente igual.
Cuando creamos informes para un cliente eso no es viable ya que una vez que el informe está creado se tiene que dejar todo automatizado para no tener que estar en un constante mantenimiento del mismo.
Tras leer el artículo de Radacad que puedes ver pinchando aquí llegué a la conclusión que lo mejor realizar una consulta web con Power Query y descargar la información de los cambios de hora desde una web y hacer el cambio de forma dinámica.
Vamos a verlo paso a paso:
✅ En primer lugar lo que hice fue acceder a la web timeanddate.com y buscar la hora de Madrid, una vez ahí accedí a Time Zone y me encontré con una tabla donde venían los diferentes cambios de hora en Madrid hasta 2027.
Creamos una consulta web y insertamos el enlace
Elegimos en HTML Tables la tabla llamada Time Changes in Madrid Over the Years
La tabla nos quedará así y tendremos que hacerle una serie de transformaciones y limpieza.
Una vez transformada la columna Year para obtener los años de cada una de las filas que se encontraban en blanco vamos a proceder a crear una columna DateTime con las Columnas Year y Date & Time. Esta columna será clave para saber cuando tenemos que cambiar a +2 o +1 en función de la fecha en la que nos encontremos.
Vamos al editor avanzado para crear una columna con la combinación de Year y Date & Time y lo transformamos a datetime.
Table.AddColumn(#"Filled Down", "Fecha cambio hora", each DateTime.FromText(Text.From([Year]) & " " & Text.Middle([#"Date & Time"], 5))),
Table.TransformColumnTypes(#"Added Custom",{{"Fecha cambio hora", type datetime}})
Así nos queda la nueva columna llamada Fecha cambio hora
De la columna Offset After necesitamos obtener el +2 o -1 que hemos comentado que cambia según el horario en el que nos encontremos por tanto vamos a crear una nueva columna para que en esa columna solo se encuentre un 2 o un 1.
Table.AddColumn(#"Changed Type3", "Time zone hours", each Text.BetweenDelimiters([Offset After], "+", "h"), type text)
Ahora vamos a obtener la hora UTC actual.
CurrentDateTime = DateTimeZone.FixedUtcNow()
Una vez que sabemos cual es nuestra hora actual necesitamos filtrar la columna «Fecha cambio hora» para ver que horas de esta columna son menor o igual que la fecha actual.
Table.SelectRows(#"Inserted Text Between Delimiters", each [Fecha cambio hora] <= DateTimeZone.RemoveZone(CurrentDateTime))
Este es el resultado que nos arroja:
Como veis el último registro es el que corresponde con la fecha con la que nos encontramos actualmente ya que el siguiente cambio de horario como hemos comentado no se realiza hasta octubre.
Como sabemos que siempre el ultimo registro va a ser el que vamos a necesitar vamos a crear una función donde nos devuelva siempre el ultimo registro del filtro anterior.
LastTimeZoneRecord = Table.LastN(#"Filtered Rows", 1)
Estas funciones se utilizan para obtener la última zona horaria válida a partir de los datos filtrados:
✅Table.LastN: Esta función devuelve el último registro de la tabla resultante después de aplicar el filtro «Filtered Rows». La función «LastN» selecciona un número específico de filas desde el final de la tabla, en este caso, solo una fila (1), que es el registro más reciente después de aplicar el filtro.
Ahora vamos a crear la columna «Fecha Actualización» esta columna va a ser la que vamos a utilizar en nuestro informe.
Table.AddColumn(#"Removed Columns1", "Fecha Actualización", each DateTimeZone.SwitchZone(CurrentDateTime, 0))
Una vez añadida nuestra columna le cambiamos el tipo de dato a datetime y ¡voilà!
En nuestro servicio tendremos la misma hora que en el desktop
Y ya sabes, si te ha resultado útil esta información ayúdame compartiéndola en tu red social favorita.
Wirklich gut geschrieben und auf den Punkt gebracht.