PowerShell file CSV errori di conversione a causa di PC con diverso formato di data e ora che il file di input

0

Domanda

Sto utilizzando PowerShell con uno script per convertire un .CSV file di dati raw in più gestibile formato dati con colonne separate, un pulitore di vista etc. E perché il file di origine con i dati grezzi è in NOI formato di data e ora (ad esempio 11/23/21, 1:00 PM), quindi se il PC è nello stesso formato di stati UNITI il processo di conversione funziona perfettamente come dovrebbe con 0 errori. MA, se il PC è in un paese diverso formato di data e ora, quindi PowerShell mostra gli errori in rosso nel processo.

Quando il PC è in un altro formato di data e ora vedo il principale errore è:

"Analizzare" con "1" argomento(i): "Stringa non riconosciuta come DateTime valido."

E il problema è il PC su cui verrà utilizzato non è in NOI formato (solo cambiato a NOI formato per il test), quindi potrebbe qualcuno per favore mi aiuti a aggiungere al processo di conversione di sintassi o frase/s semplicemente specificare direttamente nel codice un formato fisso che tiene statico formato di output in modo indipendente sull'orologio del PC formato di data e ora, e se uno degli ingressi nel file è “11/23/21, 1:00”, quindi specificare il codice si desidera che l'output nel formato “gg-MMM-aaaa hh:mm” per avere un risultato come “23-Nov-2021 01:00 PM”

La sezione di codice nello script utilizzato per la conversione:

…
$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
…

Esempio di materie prime di origine dati (il file CVS sono decine di linee, come la prossima):

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

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

...

...

E l'Output sarà simile a:

enter image description here

Ho provato con DateTime esempi in altri post qui stackoverflow.com) per regolare il codice per lavorare in un PC senza di NOI formato di data e ora e per ottenere il formato di data e ora risultato sopra descritto. Esempi come:

'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))
…

Ma con questi esempi PowerShell mostra il messaggio di errore “Impossibile associare l'argomento parametro InputObject' perché è null

Aggiornamento dopo la risposta da @Seth:

Quando cercando prossima modifica del codice, con il sistema del PC formato della data in “24-Nov-21” e lasciando il resto come sopra:

…
$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
…

quindi, PowerShell mostra i seguenti errori: enter image description here

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

Migliore risposta

1

Come è stato spiegato, è una buona idea per risolvere il CSV di avere una migliore dateformat. Un esempio potrebbe essere lo standard ISO 8601 che può essere utilizzato con Get-Date -Format "o".

Detto questo Get-Date si basa su C# roba in background. Quindi, è possibile utilizzare il codice C# per leggere che in una cultura particolare. Come si sa la cultura di origine, questo dovrebbe funzionare. Fissaggio il timestamp è ancora meglio l'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 questo codice di esempio devi assegnare $dateString il valore di $item.' Date/Time' e il risultato è che potrebbe essere il risultato di Get-Date. Così si potrebbe assegnare $dtreData.'DateTime' il risultato di tale Get-Date chiamata. In alternativa è possibile utilizzare il .NET Oggetto DateTime per convertire direttamente a una cultura particolare. Per esempio chiamando $dateTime.ToString((New-Object System.Globalization.CultureInfo("en-ES"))). Anche se non tutto ciò che di utile si può anche passare un identificatore di formato di questo metodo. Questo potrebbe essere importante se si vuole evitare la creazione di altri oggetti. Un po ' inutile chiamare sarebbe $dateTime.ToString("o", (New-Object System.Globalization.CultureInfo("en-ES"))) (come formato o è la stessa in ogni cultura).

2021-12-01 06:41:00

Grazie per la risposta @Seth, ma nessuna soluzione di sicurezza. Ho provato a modificare il codice con le linee, ma sono ancora in grado di ottenere la data e l'ora nel formato specificato direttamente nel codice, dicendo: “prendete ogni valore DateTime nel CSV file di input e di convertirli in un formato che dd-MMM-yyyy hh:mmo , ad esempio, al nome della cultura es-ESo qualcosa di simile”, cioè essere specificato direttamente nel codice, come un universale/generico modo in cui questo funziona anche se il PC è in inglese formato di data e ora, o se il PC è in spagnolo formato di data e ora, o se il PC è in francese formato di data e ora
adiario

Con le linee, ho provato la successiva modifica del codice, con il sistema del PC data in NOI 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 } e la conversione funziona senza errori, ma che dà il risultato in formato di stati UNITI & dipende l'OS formato della data.
adiario

Ho provato anche la prossima modifica del codice, con il sistema del PC formato della data in “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 e qui PowerShell dà errori dicendo: “Export-Csv : Non è possibile associare argomento parametro InputObject' perché è null”
adiario

Circa Get-Date -Format "o" $dateTime Io davvero non so da dove sarebbe il suo posto nel codice postato in questione. Ho provato a mettere in posti differenti, come nell'ultima riga, o dopo 'DateTime' = ([System.DateTime]::Parse($item.'Date/Time', $cultureInfo))o, ma PowerShell dà errori. Circa $dateString = "11/23/21, 12:58 PM"; Non ho usato questo in parte perché la vedo io sarebbe un esempio di input e in questo caso l'ingresso DateTime valori sono già nel file CSV che sono i valori che devono essere lavorato.
adiario

Nel caso In cui si sa come @Seth, potresti per favore modificare il codice postato nella domanda di cui sopra e aggiungere le necessarie modifiche per ottenere il risultato di cui ho bisogno, la data e l'ora. La ringrazio molto per il vostro tempo!
adiario

La creazione di un oggetto datetime con una cultura specifica. Vuoi il tuo $dtreData per essere Get-Date -Format "o" $dateTime. Un Get-Date utilizzando $dateTime come input dovrebbe anche usare il vostro regolare le impostazioni internazionali. In alternativa, è possibile definire in modo esplicito le impostazioni internazionali di output, ad esempio utilizzando $localDT.ToString((New-Object System.Globalization.CultureInfo("en-ES"))).
Seth

In altre lingue

Questa pagina è in altre lingue

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