PowerShell archivo CSV errores de conversión debido PC con diferente formato DateTime que el archivo de entrada

0

Pregunta

Estoy usando PowerShell con una secuencia de comandos para convertir un .CSV archivos de datos en bruto en más manejable formato de datos con columnas separadas, una visión más limpia etc. Y debido a que el archivo de origen con los datos en bruto que está en NOSOTROS formato de fecha y hora (por ejemplo, 11/23/21, 1:00 PM), entonces, si la PC está en que NOSOTROS mismos formato el proceso de conversión se ejecuta perfectamente como debe con 0 errores. PERO, si el PC es de un país diferente formato de fecha y hora, luego de PowerShell muestra los errores en rojo en el proceso.

Cuando el PC está en otro formato DateTime veo que el principal error es:

"Analizar" con "1" argumento(s): "la Cadena no fue reconocida como válida DateTime."

Y el problema es que la PC donde esta va a ser utilizado no está en NOSOTROS formato (sólo se ha cambiado a NOSOTROS formato para la prueba), así que ¿podría alguien por aquí que por favor me ayude a agregar al proceso de conversión, la sintaxis o frase/s simplemente especificar directamente en el código de un formato fijo que mantiene estático de un formato de salida de forma independiente sobre el PC reloj formato de fecha y hora, y si una de las entradas en el archivo "11/23/21, 1:00 PM", a continuación, especificar en el código que se desea que la salida en el formato "dd-MMM-aaaa hh:mm" para tener un resultado como el "23-Nov-2021 01:00 PM"

La sección de código en el script utilizado para la conversión es:

…
$data = $csvData | ? {$_ -match "\(DTRE"}

dtreFileData = New-Object System.Collections.Generic.List[PSCustomObject]

foreach ($item in $data)
{
  $null = $item.Strategy -match "\(DTRE\|(.*)\)"
  $v = $Matches[1] -split '\|'

  $resultvalue = $v[0] | Convert-CurrencyStringToDecimal
  $expectedvalue = $v[1] | Convert-CurrencyStringToDecimal

  $dtreData = [PSCustomObject]@{
    'DateTime' = ([datetime]::Parse($item.'Date/Time'))
    'ResultValue' = [decimal]$resultvalue
    'ExpectedValue' = [decimal]$expectedvalue
    }
  
  $null = $dtreFileData.Add($dtreData)
  $null = $dtreAllData.Add($dtreData)
}

$dtreFileData | Export-Csv -Path (Join-Path (Split-Path -Path $f -Parent) ($outFile + '.csv')) -Force -NoTypeInformation -Encoding ASCII
…

Ejemplo de los datos de origen (en los archivos CVS son decenas de líneas como la siguiente):

...(DTRE|49.0|48.2);...;11/23/21, 12:58 PM...;

...(DTRE|52.1|52.0);...;11/23/21, 1:00 PM...;

...

...

Y se ve el resultado:

enter image description here

He probado con DateTime ejemplos en otros posts de aquí (stackoverflow.com para ajustar el código para que funcione en un PC sin NOSOTROS formato de fecha y hora y para obtener el formato DateTime resultado descrito anteriormente. Ejemplos como:

'DateTime' = ([datetime]::Parse($item.'yyyy-MM-dd:HH:mm:ss'))

'DateTime' = ([datetime]::ParseExact($item.'yyyy-MM-dd:HH:mm:ss'))

…
$culture = [Globalization.CultureInfo]::InvariantCulture
…
  'DateTime' = ([datetime]::ParseExact($item.'yyyy-MM-dd:HH:mm:ss', $culture))
…

Pero con estos ejemplos PowerShell muestra el error "No se puede vincular el argumento del parámetro 'InputObject' porque es null"

Actualización después de la respuesta de @Seth:

Cuando se trata de la próxima modificación del código, con el PC de formato de fecha del sistema en "24-Nov-21" y dejando el resto como arriba:

…
$resultvalue = $v[0] | Convert-CurrencyStringToDecimal
$expectedvalue = $v[1] | Convert-CurrencyStringToDecimal
$cultureInfo= New-Object System.Globalization.CultureInfo("es-ES")

$dtreData = [PSCustomObject]@{
  'DateTime' = ([System.DateTime]::Parse($item.'Date/Time', $cultureInfo))
  'ResultValue' = [decimal]$resultvalue
  'ExpectedValue' = [decimal]$expectedvalue
…

entonces, PowerShell muestra el siguiente error: enter image description here

datetime powershell
2021-11-23 21:14:34
1

Mejor respuesta

1

Como se ha explicado, es una buena idea para solucionar el CSV para tener una mejor dateformat. Un ejemplo sería la norma ISO 8601 que puede ser utilizado con Get-Date -Format "o".

Que dice Get-Date se basa en C# cosas en el fondo. Así que usted puede utilizar C# código para leer que en una cultura particular. Como usted sabe, el origen de la cultura, esto debe funcionar. La fijación de la marca de tiempo es aún una mejor idea.

$cultureInfo= New-Object System.Globalization.CultureInfo("en-US")
$dateString = "11/23/21, 12:58 PM";
$dateTime = [System.DateTime]::Parse($dateString, $cultureInfo);
Get-Date -Format "o" $dateTime

Con este código de ejemplo a usted le asigne $dateString el valor de $item.' Date/Time' y el resultado es probable que usted desea que sería el resultado de Get-Date. Así que se le asigne $dtreData.'DateTime' el resultado de esa Get-Date de la llamada. Alternativamente, es posible utilizar la .NET Objeto DateTime para convertir directamente a una cultura particular. Por ejemplo llamando $dateTime.ToString((New-Object System.Globalization.CultureInfo("en-ES"))). Aunque no es del todo útil también podría pasar el formato de identificador para este método. Esto podría ser relevante si desea evitar la creación de objetos adicionales. Un poco de la llamada innecesaria sería $dateTime.ToString("o", (New-Object System.Globalization.CultureInfo("en-ES"))) (como formato o es el mismo en todas las culturas).

2021-12-01 06:41:00

Gracias por tu respuesta @Seth, pero no hay solución todavía. He intentado modificar el código con sus líneas, pero todavía soy incapaz de obtener la fecha y la hora en un formato especificado directamente en el código, diciendo: "toma cada valor de DateTime en el CSV archivo de entrada y convertirlos al formato dd-MMM-yyyy hh:mmo , por ejemplo, a la cultura nombre es-ESo algo similar", es decir, se especifican directamente en el código como un universal o genérico de manera que esto funciona sin importar si el PC está en inglés, formato de fecha y hora, o si la PC está en español, formato de fecha y hora, o si la PC está en francés formato de fecha y hora
adiario

Con sus líneas, he intentado de la siguiente modificación del código, con el sistema de PC fecha en NOSOTROS formato: $resultvalue = $v[0] | Convert-CurrencyStringToDecimal $expectedvalue = $v[1] | Convert-CurrencyStringToDecimal $cultureInfo= New-Object System.Globalization.CultureInfo("en-US") $dtreData = [PSCustomObject]@{ 'DateTime' = ([System.DateTime]::Parse($item.'Date/Time', $cultureInfo)) 'ResultValue' = [decimal]$resultvalue 'ExpectedValue' = [decimal]$expectedvalue } y la conversión funciona sin errores, pero dando el resultado en NOSOTROS formato y ser dependiente en el sistema de formato de fecha.
adiario

También probé con la siguiente modificación del código, con el PC de formato de fecha del sistema en "24-Nov-21": …$resultvalue = $v[0] | Convert-CurrencyStringToDecimal $expectedvalue = $v[1] | Convert-CurrencyStringToDecimal $cultureInfo= New-Object System.Globalization.CultureInfo("es-ES") $dtreData = [PSCustomObject]@{ 'DateTime' = ([System.DateTime]::Parse($item.'Date/Time', $cultureInfo)) 'ResultValue' = [decimal]$resultvalue 'ExpectedValue' = [decimal]$expectedvalue y aquí PowerShell da errores diciendo: "la Exportación Csv : No se puede vincular el argumento del parámetro 'InputObject' porque es"null"
adiario

Acerca de Get-Date -Format "o" $dateTime La verdad, no sé donde estaría su lugar en el código publicados en la pregunta. Traté de poner en varios lugares como en la última línea, o después de 'DateTime' = ([System.DateTime]::Parse($item.'Date/Time', $cultureInfo))o en ella, pero PowerShell da errores. Acerca de $dateString = "11/23/21, 12:58 PM"; Yo no uso esta parte, ya veo que sería un ejemplo de entrada y en este caso la entrada de valores DateTime ya están en el archivo CSV que son los valores que necesitan ser resueltos.
adiario

En caso de que usted sabe cómo @Seth, por favor podría modificar el código publicado en la pregunta anterior y añadir las modificaciones necesarias para tener el resultado que necesita para la fecha y la hora. Muchas gracias por su tiempo!
adiario

Se está creando un objeto datetime con una cultura específica. Que quieres es que tu $dtreData para ser Get-Date -Format "o" $dateTime. Un Get-Date el uso de $dateTime como entrada también debe usar su regular de la configuración regional. Alternativamente, usted puede definir explícitamente la configuración regional de salida utilizando, por ejemplo, $localDT.ToString((New-Object System.Globalization.CultureInfo("en-ES"))).
Seth

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................