PowerShell CSV file conversion chyby, kvůli PC s různými DateTime formát vstupního souboru

0

Otázka

Jsem pomocí PowerShell skript převést .CSV raw datový soubor do více zvládnutelné formátu dat s samostatných sloupcích, čistší zobrazení atd. A protože zdrojový soubor s raw dat je v NÁS formát data a času (např. 11/23/21, 1:00 PM), pak pokud je PC ve stejném formátu US procesu konverze běží perfektně, jako by se s 0 chyb. ALE pokud je PC v jiné zemi, formát data a času, pak PowerShell ukazuje chyby v červené v procesu.

Když je PC v jiné formát DateTime vidím, že hlavní chyba je:

"Parse" s "1" argument(y): "Řetězec nebyl rozpoznán jako platný DateTime."

A problém je v PC, kde to bude použito, je v NÁS není formát (pouze se změnil na NÁS formát pro testování), tak může tady někdo prosím, pomozte mi, jak přidat do procesu konverze syntaxe nebo větu/y, aby jednoduše zadat přímo v kódu, pevný formát, který udržuje statickou výstupní formát nezávisle o PC hodiny formát data a času, a pokud jeden ze vstupů do souboru je "11/23/21, 1:00 HODIN" pak specifikovat v kódu, chcete výstup ve formátu "dd-MMM-rrrr hh:mm" , aby se výsledek jako "23-Nov-2021 01:00 PM"

Části kódu ve skriptu použit pro převod je:

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

Příklad surového zdroj dat (v CVS souboru jsou desítky linek, jako další):

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

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

...

...

A Výstup vypadá takto:

enter image description here

Snažil jsem se s DateTime příklady v jiných příspěvků zde (stackoverflow.com) pro nastavení kódu pro práci v PC bez NÁS formát data a času a ten formát DateTime výsledkem je popsáno výše. Příklady, jako:

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

Ale s těmito příklady PowerShell zobrazí chyba "Nelze vytvořit vazbu argument pro parametr 'InputObject, protože je null"

Aktualizace po odpovědi od @Seth:

Když se snaží další modifikace kódu, s PC systému formát data v "24-Nov-21" a opouštět zbytek jako výše:

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

pak, PowerShell ukazuje následující chyby: enter image description here

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

Nejlepší odpověď

1

Jak již bylo vysvětleno, že je to dobrý nápad, aby opravit CSV mít lepší dateformat. Příkladem by mohl být, ISO 8601, který může být použit s Get-Date -Format "o".

Že řekl, že Get-Date spoléhá na C# věci v pozadí. Takže můžete použít C# kód číst , že v určité kultuře. Jak víte, původu kultury by to mělo fungovat. Stanovení časové razítko je ještě lepší nápad.

$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

Tento příklad kódu byste přiřadit $dateString hodnota $item.' Date/Time' a výsledek vás pravděpodobně chtít bude výsledek Get-Date. Takže byste přiřadit $dtreData.'DateTime' výsledek Get-Date volání. Alternativně je možné použít .NET DateTime Objekt přímo převést do konkrétní kultury. Například tím, že volá $dateTime.ToString((New-Object System.Globalization.CultureInfo("en-ES"))). I když ne všechny, že užitečné, můžete také předat identifikátor formátu k této metodě. To může být důležité, pokud chcete, aby se zabránilo vytváření dalších objektů. Poněkud zbytečné volání by být $dateTime.ToString("o", (New-Object System.Globalization.CultureInfo("en-ES"))) (jako formát o. je stejná v každé kultuře).

2021-12-01 06:41:00

Díky za reakce @Seth ale žádné řešení dosud. Zkoušel jsem modifikovat kód s textem, ale já jsem stále schopen získat datum a čas ve formátu, který je zadán přímo v kódu, říkat "vzít každý DateTime hodnoty v CSV souboru vstupní soubor a převést je do formátu dd-MMM-yyyy hh:mm, nebo například ke kultuře název es-ESnebo něco podobného", tj. být zadán přímo v kódu jako univerzální/obecný způsob, kde to funguje bez ohledu na to jestli je PC v angličtině formát data a času, nebo pokud je PC ve španělštině formát data a času, nebo pokud je PC ve francouzštině formát data a času
adiario

S vašimi řádky, jsem se snažil další modifikace kódu, s PC systémové datum ve formátu US: $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 } a konverze funguje bez chyby, ale dává výsledek v US formátu a jsou závislé na OS formát data.
adiario

Zkoušel jsem i další úprava kodexu, s PC systému formát data v "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 a tady PowerShell dává chybám, říká: "Export-Csv : Nelze vázat argument pro parametr 'InputObject, protože je null"
adiario

O Get-Date -Format "o" $dateTime Já opravdu nevím, kde by bylo jeho místo v zaslán kód v otázce. Snažil jsem se dát to na více místech, jako v posledním řádku, nebo po 'DateTime' = ([System.DateTime]::Parse($item.'Date/Time', $cultureInfo))nebo se na to, ale PowerShell dává chybám. O $dateString = "11/23/21, 12:58 PM"; Nechtěl jsem použít tuto část, protože vidím, že to bude vstupní příklad a v tomto případě vstup DateTime hodnoty jsou již do CSV souboru, které jsou hodnoty, které je třeba pracoval.
adiario

V případě, že víte, jak @Seth, mohl bys, prosím, upravit kód publikováno v otázce výše a přidat potřebné úpravy, aby výsledek potřebuji pro datum a čas. Děkuji moc za váš čas!
adiario

Vytváření datetime objekt s konkrétní kulturou. Ty chceš, aby tvoje $dtreData být Get-Date -Format "o" $dateTime. A Get-Date pomocí $dateTime jako vstup by měl také používat své pravidelné místo. Alternativně můžete explicitně definovat locale na výstupu např. pomocí $localDT.ToString((New-Object System.Globalization.CultureInfo("en-ES"))).
Seth

V jiných jazycích

Tato stránka je v jiných jazycích

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