¿Cómo creo un campo de fecha y hora a partir de un campo de fecha y un campo de número?

Un usuario Pregunto ✅

d474boy

Hola a todos, esta es mi primera publicación en los foros de la comunidad de Power BI

También soy muy nuevo en Power Query y el lenguaje M.

De todos modos, tengo una consulta que está sacando dos campos que son ‘Fecha de finalización’ y ‘Hora de finalización’, pero la hora es solo un número decimal. El número decimal es algo así como 10,3, pero esto en realidad significa 10:30.

Quiero combinar la fecha y el número en una sola columna llamada Completed_DateTime. En Excel, esto sería tan simple como la siguiente fórmula:

Completed_DateTime = Completed_Date + INT (Número) / 24 + 100 * MOD (Número, 1) / 24/60

Lo mejor que se me ocurrió en Power Query es:

# «Add Temp End_DateTime col» = Table.AddColumn (# «Eliminar 1-1-1900 Dates», «Actual_End_DateTime», cada [Actual_End_Date]),
# «Cambiar el tipo de columna temporal a DateTime» = Table.TransformColumnTypes (# «Agregar columna Temp End_DateTime», {{«Actual_End_DateTime», tipo datetime}}),
# «Crear el End_DateTime real» = Table.AddColumn (# «Cambiar el tipo de columna temporal a DateTime», «Actual_End_DateTime2», cada [Actual_End_DateTime] + #duration (0, Number.RoundDown ([Actual_End_Time]), Number.RoundDown (100 * Number.Mod ([Actual_End_Time], 1)), 0)),

Seguramente se podría hacer en un solo paso. Por ejemplo, puedo crear

Hola @ d474boy

Agregar una columna personalizada

Text.Combine
({
   Text.From(Date.AddDays([Completed Date], Int64.From(
    [Completed Time]/24)), "en-US"), 
   Text.From(Text.Combine
       ({Text.From(Int64.From([Completed Time]), "en-US"),
         Text.From(Int64.From(100*Number.Mod([Completed Time],1)), "en-US")}, ":"),
    "en-US")}, 
":")

Capture14.JPG

Atentamente
Maggie

Equipo de apoyo de la comunidad _ Maggie Li
Si esta publicación ayuda, entonces por favor considere Acéptalo como la solución para ayudar a los demás miembros a encontrarlo más rápidamente.

gpoggi

Hola @ d474boy

Sí, hay diferentes formas de lograr esto, por ejemplo, si su Fecha completada nunca es nulo, puedes probar solo esta línea:

#datetime(Date.Year([Completed_Date]),Date.Month([Completed_Date]), Date.Day([Completed_Date]), Number.RoundDown([Number]),Number.Mod([Number],1)*100,0)

si tiene nulos, agregue una condición simple:

if
  [Completed_Date] = null
then
  null
else 
  #datetime(Date.Year([Completed_Date]),Date.Month([Completed_Date]), Date.Day([Completed_Date]), Number.RoundDown([Number]),Number.Mod([Number],1)*100,0)

Espero que esto ayude,

Cualquier pregunta, házmelo saber

Saludos,

Gian Carlo Poggi

d474boy

En respuesta a gpoggi

Hola @gpoggi

He descubierto cómo agregar su código inteligente, como se muestra a continuación:

# «Rename Raw Fieldnames» = Table.RenameColumns (# «Formatear DataDatetime como datetime», {{«ORDER_C», «OrderNumber»}, {«CONTRACT_C», «ContractCode»}, {«CRSTAMP_C», «ReceivedDatetime»}, {«DESC_C», «OrderDescription»}, {«PRIORITY_C», «PriorityCode»}, {«CMPRDT_C», «ActualEndDate»}, {«SCTIME_C», «ActualEndTime»}, {«RTREATM_C», «JobType»}, {«USRN_C», «USRN»}, {«LOCN_C», «DefectLocation»}}),
# «Remove 1-1-1900 Dates» = Table.ReplaceValue (# «Rename Raw Fieldnames», # date (1900, 1, 1), null, Replacer.ReplaceValue, {«ActualEndDate»}),
# «Create CompletedDatetime» = Table.AddColumn (# «Eliminar 1-1-1900 Fechas», «CompletedDatetime», cada si
[ActualEndDate] = nulo
luego
nulo
demás
#datetime (Date.Year ([ActualEndDate]), Fecha.Mes ([ActualEndDate]), Dia de cita([ActualEndDate]), Number.RoundDown ([ActualEndTime]), Number.Mod ([ActualEndTime], 1) * 100,0)),
# «Columnas eliminadas» = Table.RemoveColumns (# «Create CompletedDatetime», {«ActualEndDate», «ActualEndTime»}),

Sin embargo, esto está dando un error cuando el campo numérico (ActualEndTime) no es un número entero. El campo tiene el formato DecimalNumber y tiene valores para filas secuenciales de: 0, 14, 10,42, etc.

He superado el error agregando un Number.Round () al Number.Mod ([ActualEndTime], 1) * 100 partes, por lo que mi código lee normalmente:

# «Rename Raw Fieldnames» = Table.RenameColumns (# «Formatear DataDatetime como datetime», {{«ORDER_C», «OrderNumber»}, {«CONTRACT_C», «ContractCode»}, {«CRSTAMP_C», «ReceivedDatetime»}, {«DESC_C», «OrderDescription»}, {«PRIORITY_C», «PriorityCode»}, {«CMPRDT_C», «ActualEndDate»}, {«SCTIME_C», «ActualEndTime»}, {«RTREATM_C», «JobType»}, {«USRN_C», «USRN»}, {«LOCN_C», «DefectLocation»}}),
# «Remove 1-1-1900 Dates» = Table.ReplaceValue (# «Rename Raw Fieldnames», # date (1900, 1, 1), null, Replacer.ReplaceValue, {«ActualEndDate»}),
# «Create CompletedDatetime» = Table.AddColumn (# «Eliminar 1-1-1900 Fechas», «CompletedDatetime», cada si
[ActualEndDate] = nulo
luego
nulo
demás
#datetime (Date.Year ([ActualEndDate]), Fecha.Mes ([ActualEndDate]), Dia de cita([ActualEndDate]), Number.RoundDown ([ActualEndTime]),Número Redondo (Number.Mod ([ActualEndTime], 1) * 100), 0)),
# «Columnas eliminadas» = Table.RemoveColumns (# «Create CompletedDatetime», {«ActualEndDate», «ActualEndTime»}),

No sé por qué fue necesario este ajuste, pero al menos funciona.

Gracias por tu ayuda.

gpoggi

En respuesta a d474boy

Hola @ d474boy,

Probablemente sea por los datos de entrada, si puedes arreglarlo con Number.Round antes del Number.Mod, genial, si no solo envía una pantalla de tu tabla para ver cómo se generaron los datos hasta el paso # «Eliminar las fechas 1-1-1900». Y te ayudaría a encontrar la razón de por qué se muestra ese error.

Cualquier pregunta, házmelo saber.

Saludos,

Gian Carlo Poggi

d474boy

En respuesta a gpoggi

Hola @gpoggi

El código completo es:

dejar
Fuente = Sql.Databases («XXXXXXXXXXXXX»),
cpa_LIVE = Fuente {[Name=»YYYYYYYYY»]}[Data],
dbo_SWOL = cpa_LIVE {[Schema=»dbo»,Item=»SWOL»]}[Data],
# «Filtered Rows» = Table.SelectRows (dbo_SWOL, cada [SN] = «506501» y ([CONTRACT_C] = «GH1901» o [CONTRACT_C] = «GH2001»)),
# «Otras columnas eliminadas» = Table.SelectColumns (# «Filas filtradas», {«CONTRACT_C», «ORDER_C», «CMPRDT_C», «CRSTAMP_C», «LOCN_C», «PRIORITY_C», «SCTIME_C», «RTREATM_C», «USRN_C», «DESC_C»}),
# «Tipo modificado» = Table.TransformColumnTypes (# «Otras columnas eliminadas», {{«CMPRDT_C», escriba fecha}}),
# «Texto recortado» = Table.TransformColumns (# «Tipo cambiado», {{«LOCN_C», Text.Trim, escriba texto}}),
# «Texto limpio» = Table.TransformColumns (# «Texto recortado», {{«LOCN_C», Text.Clean, escriba texto}}),
# «Texto recortado1» = Table.TransformColumns (# «Texto limpio», {{«DESC_C», Text.Trim, escriba texto}}),
# «Texto limpio1» = Table.TransformColumns (# «Texto recortado1», {{«DESC_C», Text.Clean, escriba texto}}),
# «Crear campo TownName» = Table.AddColumn (# «Texto limpio1», «TownName», cada Text.Start ([LOCN_C], Text.PositionOf ([LOCN_C], «») +1)),
# «Reordenar columnas» = Table.ReorderColumns (# «Crear campo TownName», {«ORDER_C», «CRSTAMP_C», «DESC_C», «PRIORITY_C», «CMPRDT_C», «RTREATM_C», «USRN_C», «LOCN_C», «Nombre del pueblo»}),
# «Agregar campo DataDatetime» = Table.AddColumn (# «Reordenar columnas», «DataDatetime», cada DateTime.LocalNow ()),
# «Format DataDatetime as datetime» = Table.TransformColumnTypes (# «Agregar campo DataDatetime», {{«DataDatetime», escriba datetime}}),
# «Rename Raw Fieldnames» = Table.RenameColumns (# «Formatear DataDatetime como datetime», {{«ORDER_C», «OrderNumber»}, {«CONTRACT_C», «ContractCode»}, {«CRSTAMP_C», «ReceivedDatetime»}, {«DESC_C», «OrderDescription»}, {«PRIORITY_C», «PriorityCode»}, {«CMPRDT_C», «ActualEndDate»}, {«SCTIME_C «,» ActualEndTime «}, {«RTREATM_C», «JobType»}, {«USRN_C», «USRN»}, {«LOCN_C», «DefectLocation»}}),
# «Remove 1-1-1900 Dates» = Table.ReplaceValue (# «Rename Raw Fieldnames», # date (1900, 1, 1), null, Replacer.ReplaceValue, {«ActualEndDate»}),
# «Create CompletedDatetime» = Table.AddColumn (# «Eliminar 1-1-1900 Dates», «CompletedDatetime», cada uno si
[ActualEndDate] = nulo
luego
nulo
demás
#datetime (Date.Year ([ActualEndDate]), Fecha.Mes ([ActualEndDate]), Dia de cita([ActualEndDate]), Number.RoundDown ([ActualEndTime]), Number.Round (Number.Mod ([ActualEndTime], 1) * 100), 0)),
# «Columnas eliminadas» = Table.RemoveColumns (# «Create CompletedDatetime», {«ActualEndDate», «ActualEndTime»}),
# «Columnas reordenadas» = Table.ReorderColumns (# «Columnas eliminadas», {«OrderNumber», «ContractCode», «ReceivedDatetime», «CompletedDatetime», «OrderDescription», «PriorityCode», «JobType», «USRN», » DefectLocation «,» TownName «,» DataDatetime «})
en
# «Columnas reordenadas»

He notado que el tipo de campo para el SCTIME_C «(renombrado a» ActualEndTime «) El campo es Número decimal. Lo que sospecho es que la función #datetime requiere que todos sus argumentos sean enteros. Entonces, aunque todos los valores en el campo SCTIME_C solo tienen 2 lugares decimales (por ejemplo, 10.59) y, por lo tanto, al hacer el * 100, los resultados siempre serán enteros (por ejemplo, 59), #datetime no puede estar seguro de esto y, por lo tanto, rechaza el valores. Sin embargo, cuando el valor en el campo SCTIME_C era algo así como 13, la función #datetime funcionó bien, es decir, crearía una fecha y hora del 04/04/2019 13:00:00, por ejemplo. Entonces, ¿por qué esta inconsistencia?

d474boy

En respuesta a gpoggi

Hola @gpoggi

Gracias por la ayuda.

¿Cómo implemento realmente ese código? No entiendo la sintaxis lo suficientemente bien como para introducir esto. He copiado en la sección de mi código desde un poco antes del bit que crea el campo hasta justo después. Por favor, podría agregar su bit (que se muestra a continuación) exactamente en la sintaxis requerida.

if
  [Completed_Date] = null
then
  null
else 
  #datetime(Date.Year([Completed_Date]),Date.Month([Completed_Date]), Date.Day([Completed_Date]), Number.RoundDown([Number]),Number.Mod([Number],1)*100,0)

# «Remove 1-1-1900 Dates» = Table.ReplaceValue (# «Rename Raw Fieldnames», # date (1900, 1, 1), null, Replacer.ReplaceValue, {«ActualEndDate»}),
# «Add TempCompletedDatetime» = Table.AddColumn (# «Eliminar 1-1-1900 fechas», «TempCompletedDatetime», cada [ActualEndDate]),
# «Cambiar el tipo de campo temporal a DateTime» = Table.TransformColumnTypes (# «Agregar TempCompletedDatetime», {{«TempCompletedDatetime», escriba datetime}}),
# «Create the real CompletedDateTime» = Table.AddColumn (# «Cambiar el tipo de campo temporal a DateTime», «TempCompletedDatetime2», cada [TempCompletedDatetime] + #duration (0, Number.RoundDown ([ActualEndTime]), Number.RoundDown (100 * Number.Mod ([ActualEndTime], 1)), 0)),
# «Columnas eliminadas» = Table.RemoveColumns (# «Crear el CompletedDateTime real», {«TempCompletedDatetime», «ActualEndDate», «ActualEndTime»}),

Por ejemplo, para mostrar lo poco que entiendo, intenté lo siguiente usando la versión más simple de su solución:

# «Remove 1-1-1900 Dates» = Table.ReplaceValue (# «Rename Raw Fieldnames», # date (1900, 1, 1), null, Replacer.ReplaceValue, {«ActualEndDate»}),
# «Add TempCompletedDatetime» = Table.AddColumn (# «Eliminar 1-1-1900 fechas», «TempCompletedDatetime», cada #datetime (Date.Year ([Completed_Date]), Fecha.Mes ([Completed_Date]), Dia de cita([Completed_Date]), Number.RoundDown ([Number]), Number.Mod ([Number], 1) * 100,0),
# «Cambiar el tipo de campo temporal a DateTime» = Table.TransformColumnTypes (# «Agregar TempCompletedDatetime», {{«TempCompletedDatetime», escriba datetime}}),
# «Create the real CompletedDateTime» = Table.AddColumn (# «Cambiar el tipo de campo temporal a DateTime», «TempCompletedDatetime2», cada [TempCompletedDatetime] + #duration (0, Number.RoundDown ([ActualEndTime]), Number.RoundDown (100 * Number.Mod ([ActualEndTime], 1)), 0)),
# «Columnas eliminadas» = Table.RemoveColumns (# «Crear el CompletedDateTime real», {«TempCompletedDatetime», «ActualEndDate», «ActualEndTime»}),

Muchas gracias

Gareth

Deja un comentario

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