Ошибки преобразования файлов PowerShell CSV из-за ПК с другим форматом даты и времени, чем входной файл

0

Вопрос

Я использую PowerShell со сценарием для преобразования файла необработанных данных .CSV в более удобный формат данных с отдельными столбцами, более чистым представлением и т. Д. И поскольку исходный файл с необработанными данными находится в формате даты и времени США (например, 23.11.2011, 1:00 вечера), то, если компьютер находится в том же формате США, процесс преобразования выполняется идеально, как и должно быть, с 0 ошибками. НО если компьютер находится в другом формате даты и времени страны, то PowerShell показывает ошибки красным цветом в процессе.

Когда компьютер находится в другом формате даты и времени, я вижу, что основная ошибка заключается в:

"Синтаксический анализ" с аргументом(ами) "1": "Строка не была распознана как допустимая дата-время".

И проблема в ПК, где они будут использоваться не в американском формате (только поменяли нам формат для тестирования), так что может тут кто-то пожалуйста, помогите мне, чтобы добавить в процесс преобразования синтаксиса предложения/s, чтобы просто указать непосредственно в коде фиксированный формат, что держит статические формат вывода самостоятельно о ПК часы формат даты и времени, и если один из входов в файл “11/23/21, 1:00 ПМ”, а затем указать код, который вы хотите вывод в формате “ДД-МММ-гггг чч:мм” , чтобы иметь результат, как “23-ноября-2021 01:00 часов”

Раздел кода в скрипте, используемом для преобразования, является:

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

Пример необработанных исходных данных (в файле CVS десятки строк, подобных следующей):

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

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

...

...

И результат выглядит так:

enter image description here

Я пробовал использовать примеры DateTime в других сообщениях отсюда (stackoverflow.com) настроить код для работы на ПК без использования формата даты и времени и получить результат в формате даты и времени, описанный выше. Примеры, такие как:

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

Но в этих примерах PowerShell показывает ошибку “Невозможно привязать аргумент к параметру 'InputObject', потому что он равен нулю”.

Обновление после ответа от @Seth:

При попытке следующей модификации кода, с форматом системной даты ПК в “24-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
…

затем PowerShell показывает следующие ошибки: enter image description here

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

Лучший ответ

1

Как было объяснено, это хорошая идея, чтобы исправить CSV, чтобы иметь лучший формат даты. Примером может служить ISO 8601, который можно использовать сGet-Date -Format "o".

Это говорит о том, что дата получения зависит от материала C# в фоновом режиме. Таким образом, вы можете использовать код C# для чтения этого в определенной культуре. Как вы знаете культуру происхождения, это должно сработать. Исправление метки времени все еще является лучшей идеей.

$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

С помощью этого примера кода вы бы назначили $dateString значение $item.' Date/Time' и результат, которого вы, вероятно, хотите, будет результатом Get-Date. Таким образом, вы бы назначили $dtreData.'DateTime' в результате этого Get-Date вызов. В качестве альтернативы можно использовать объект .NET DateTime для прямого преобразования в определенную культуру. Например, позвонив $dateTime.ToString((New-Object System.Globalization.CultureInfo("en-ES"))). Хотя это и не так уж полезно, вы также можете передать идентификатор формата этому методу. Это может быть актуально, если вы хотите избежать создания дополнительных объектов. Несколько ненужный звонок был бы $dateTime.ToString("o", (New-Object System.Globalization.CultureInfo("en-ES"))) (поскольку формат o одинаков в каждой культуре).

2021-12-01 06:41:00

Спасибо за ваш ответ @Seth, но решения пока нет. Я попытался изменить код с помощью ваших строк, но я все еще не могу получить дату и время в формате, указанном непосредственно в коде, сказав: “возьмите каждое значение даты и времени во входном файле CSV и преобразуйте их в формат dd-MMM-yyyy hh:mm, или, например, к названию культуры es-ES, или что-то подобное”, т. е. указывается непосредственно в коде как универсальный/универсальный способ, где это работает независимо от того, находится ли компьютер в формате даты и времени на английском языке, или если компьютер находится в формате даты и времени на испанском языке, или если компьютер находится во французском формате даты и времени
adiario

С вашими строками я попробовал следующую модификацию кода, с системной датой ПК в американском формате: $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 } и преобразование работает без ошибок, но дает результат в формате США и зависит от формата даты операционной системы.
adiario

Я также попробовал следующую модификацию кода с форматом системной даты ПК в “24-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 и здесь PowerShell выдает ошибки, говорящие: “Экспорт-Csv : Не удается привязать аргумент к параметру 'InputObject', потому что он равен нулю”.
adiario

О нас Get-Date -Format "o" $dateTime Я действительно не знаю, где будет его место в опубликованном коде в вопросе. Я попытался поместить его в нескольких местах, например, в последней строке или после 'DateTime' = ([System.DateTime]::Parse($item.'Date/Time', $cultureInfo)), или в него, но PowerShell выдает ошибки. О нас $dateString = "11/23/21, 12:58 PM"; Я не использовал эту часть, потому что вижу, что это будет пример ввода, и в этом случае входные значения даты и времени уже находятся в файле CSV, которые являются значениями, которые необходимо обработать.
adiario

В случае, если вы знаете, как @Seth, не могли бы вы, пожалуйста, изменить код, опубликованный в вопросе выше, и добавить в него необходимые изменения, чтобы получить результат, который мне нужен для даты и времени. Большое вам спасибо за потраченное время!
adiario

Вы создаете объект datetime с определенной культурой. Вы бы хотели, чтобы ваш $dtreData быть Get-Date -Format "o" $dateTime. А Get-Date с помощью $dateTime в качестве входных данных также следует использовать ваш обычный язык. В качестве альтернативы вы можете явно определить языковой стандарт для вывода, например, с помощью $localDT.ToString((New-Object System.Globalization.CultureInfo("en-ES"))).
Seth

На других языках

Эта страница на других языках

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