Błąd konwersji plików PowerShell CSV z powodu KOMPUTERZE z innym formatem daty i czasu, niż plik wejściowy

0

Pytanie

Używam PowerShell ze scenariuszem do konwersji pliku danych surowych .CSV w bardziej wygodny format danych z osobnymi kolumnami, bardziej czyste występem itp., a ponieważ oryginalny plik z nieprzetworzone dane (w formacie daty i czasu w USA (na przykład, 23.11.2011, 1:00), a następnie, jeśli komputer znajduje się w tym samym formacie USA, proces konwersji odbywa się idealnie, tak jak powinno być, z 0 błędów. ALE jeśli komputer znajduje się w innym formacie daty i czasu w kraju, to PowerShell pokazuje błędy na czerwono w procesie.

Gdy komputer znajduje się w innym formacie daty i czasu, widzę, że podstawowy błąd polega na:

"Analizy" z argumentem(ami) "1": "Wiersz nie została rozpoznana jako dopuszczalna data-czas".

I problem w KOMPUTERZE, w którym będą używane w amerykańskim formacie (tylko zmienili nam format do testowania), więc może tu ktoś proszę mi pomóc, aby dodać w proces konwersji składni zdania/s, aby określić bezpośrednio w kodzie stały format, co trzyma statyczny format wyjściowy samodzielnie o PC zegar format daty i czasu, i jeśli jedno z wejść w plik "11/23/21, 1:00 PM", a następnie podać kod, który chcesz stwierdzić się w formacie "DD-MMM-rrrr gg:mm" , aby mieć wynik, jak "23-listopada-2021 01:00"

Sekcja kodu w skrypcie, który jest używany do konwersji, jest:

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

Przykład surowych danych źródłowych (w pliku CVS dziesiątki wierszy, takich następnej):

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

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

...

...

I wynik wygląda tak:

enter image description here

Próbowałem użyć przykłady DateTime w innych postach stąd (stackoverflow.com) dostosować kod do pracy na KOMPUTERZE bez korzystania z formatu daty i czasu i uzyskać wynik w formacie daty i czasu, opisany powyżej. Przykłady, takie jak:

'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 w tych przykładach PowerShell pokazuje się błąd:"nie można powiązać argument do opcji 'InputObject', bo jest on równy zeru".

Aktualizacja po odpowiedzi od @Seth:

Przy próbie kolejnej modyfikacji kodu, z formatem daty systemowej KOMPUTERA w "24-21 listopada" i pozostawiając resztę jak wyżej:

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

następnie PowerShell pokazuje następujące błędy: enter image description here

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

Najlepsza odpowiedź

1

Jak zostało wyjaśnione, że to dobry pomysł, aby naprawić pliku CSV, aby mieć najlepszy format daty. Przykładem może służyć ISO 8601, który można używać zGet-Date -Format "o".

To mówi o tym, że data otrzymania zależy od materiału, z C# w tle. W ten sposób, można użyć kod C# do czytania tego w określonej kulturze. Jak wiecie kulturę pochodzenia, to powinno zadziałać. Poprawka znacznika czasu wciąż jest najlepszym pomysłem.

$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

Za pomocą tego przykładu kodu można by wyznaczyli $dateString wartość $item.' Date/Time' i wynik, którego, prawdopodobnie chcesz, będzie wynikiem Get-Date. W ten sposób, by wyznaczyli $dtreData.'DateTime' w wyniku tego Get-Date wyzwanie. Jako alternatywy można użyć obiektu .NET DateTime do bezpośredniej konwersji w określoną kulturę. Na przykład dzwoniąc $dateTime.ToString((New-Object System.Globalization.CultureInfo("en-ES"))). Choć nie jest to tak przydatne, można również przekazać identyfikator formatu tej metody. To może być ważne, jeśli chcesz uniknąć tworzenia dodatkowych obiektów. Kilka niepotrzebny telefon był $dateTime.ToString("o", (New-Object System.Globalization.CultureInfo("en-ES"))) (ponieważ format o. jest taki sam w każdej kulturze).

2021-12-01 06:41:00

Dzięki za odpowiedź @Seth, ale decyzji jeszcze nie ma. Próbowałem zmienić kod za pomocą swoich wierszy, ale nadal nie mogę uzyskać datę i czas w formacie określonym bezpośrednio w kodzie, mówiąc: "weź każda wartość daty i czasu w wejściowym pliku CSV i przekształcić je w formacie dd-MMM-yyyy hh:mmlub , na przykład, do nazwy kultury es-ESlub coś podobnego", tzn. podaje się bezpośrednio w kodzie jako uniwersalny/uniwersalny sposób, gdzie to działa niezależnie od tego, czy komputer jest w formacie daty i czasu w języku angielskim, lub jeśli komputer jest w formacie daty i czasu w języku hiszpańskim, lub jeśli komputer znajduje się we francuskim formacie daty i czasu
adiario

Ze swoimi wierszami próbowałem następującą modyfikację kodu, z daty systemowej KOMPUTERA w amerykańskim formacie: $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 } i konwersja działa bez błędów, ale daje wynik w formacie USA i zależy od formatu daty systemu operacyjnego.
adiario

Próbowałem też następującą modyfikację kodu z formatem daty systemowej KOMPUTERA w "24-21 listopada".: …$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 i tu PowerShell generuje błędy, mówiące: "Export-Csv : Nie można połączyć argument do opcji 'InputObject', bo jest on równy zeru.
adiario

O nas Get-Date -Format "o" $dateTime Ja naprawdę nie wiem, gdzie będzie jego miejsce w opublikowanym kodzie w pytaniu. Próbowałem umieścić go w kilku miejscach, na przykład, w ostatnim wierszu lub po 'DateTime' = ([System.DateTime]::Parse($item.'Date/Time', $cultureInfo))lub w niego, ale PowerShell generuje błędy. O nas $dateString = "11/23/21, 12:58 PM"; Nie wykorzystał tę część, bo widzę, że to będzie przykład wprowadzania, i w tym przypadku wejściowe wartości daty i godziny znajdują się w pliku CSV, które są wartościami, które trzeba przetworzyć.
adiario

W przypadku, jeśli wiesz, jak @Seth, nie mógłbyś, proszę, zmień kod, opublikowany w pytaniu powyżej, i dodać do niego odpowiednie zmiany, aby uzyskać wynik, który jest mi potrzebny do daty i czasu. Bardzo dziękuję za poświęcony czas!
adiario

Tworzysz obiekt datetime z pewną kulturą. Chcesz, aby twój $dtreData być Get-Date -Format "o" $dateTime. A Get-Date z pomocą $dateTime jako danych wejściowych należy również użyć zwykły język. Alternatywnie można wyraźnie określić ustawienia regionalne do wyjścia, na przykład, za pomocą $localDT.ToString((New-Object System.Globalization.CultureInfo("en-ES"))).
Seth

W innych językach

Ta strona jest w innych językach

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