Попытка преобразовать строку в дату и время, используя ParseExact - PullRequest
1 голос
/ 01 июня 2019

Я пытаюсь преобразовать строку типа '5/29/2019 8:46:47 PM' в datetime для использования в качестве объекта PowerShell, но получаю сообщение об ошибке

Я пытаюсь использовать метод [datetime]::ParseExact

$Date = "5/29/2019 8:46:47 PM"

[datetime]::ParseExact($Date,'MM dd yyyy HH:mm:ss', $null)

Вместо получения объекта datetime я просто получаю эту ошибку:

Исключение вызывает "ParseExact" с аргументом (ами) "3": "Строка не была распознана какvalid DateTime. "

Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

3 голосов
/ 01 июня 2019

ответ postanote содержит эффективные решения, но стоит проанализировать проблему.

Во-первых, достаточно просто привести вашу строку к [datetime] , потому что ваша входная строка напрямую распознается в соответствии с правилами инварианта культура , которые PowerShell применяется в этом случае, независимо от текущей культуры (инвариантная культура подразумевает нейтральность к культуре и основана на культуре США и Англии):

PS> [datetime] "5/29/2019 8:46:47 PM"

Wednesday, May 29, 2019 8:46:47 PM

За кулисами PowerShell переводит это в следующий вызов:

[datetime]::Parse("5/29/2019 8:46:47 PM", [cultureinfo]::InvariantCulture)

Напротив, Get-Date чувствителен к текущей культуре:

# Works, but only in cultures that use AM / PM and place the month *first* in
# dates, notably, US-English.
PS> Get-Date -Date "5/29/2019 8:46:47 PM"

Wednesday, May 29, 2019 8:46:47 PM

Вышесказанное не сработает в таких культурах, как fr-FR (французский (Франция)), где на первом месте стоит день .

Это прискорбное несоответствие в поведении преобразования типов данных между приведениями и параметрами командлетов - давняя ошибка, задокументированная в этой проблеме GitHub ; однако из соображений обратной совместимости он не будет исправлен.


Что касается , что вы пытались :

Как указывает Lee_Daily , ваша проблема в том, что ваша строка формата, 'MM dd yyyy HH:mm:ss' не соответствует введенной строке даты, "5/29/2019 8:46:47 PM":

  • HH представляет час дня в 24-часовом формате, тогда как ваш ввод использует 12-часовой формат.

  • PM в вашем вводе не представлен в строке формата; используйте tt для общего представления спецификатора AM / PM.

  • Вы используете пробелы для разделения компонентов даты, тогда как во входной строке используется /

  • В строке формата указывается двойной -значный компонент месяца (MM; например, 05), тогда как вход имеет только одну цифру (5).

Следовательно, вы должны были использовать следующее:

PS> [datetime]::ParseExact('5/29/2019 8:46:47 PM','M/d/yyyy h:mm:ss tt', [cultureinfo]::InvariantCulture)

Wednesday, May 29, 2019 8:46:47 PM

Обратите внимание на использование [cultureinfo]::InvariantCulture вместо $null, так как последний по умолчанию будет использовать current culture, что означает, что вызов может завершиться ошибкой в ​​культурах, которые используют локализованные обозначения AM / PM (например, , во вьетнамской культуре (vi-VN), обозначения SA / CH).

Конечно, вы могли бы также использовать соответствующую конкретную культуру, например en-US (английский (США)) (или предположить, что ваш код никогда не будет работать с какой-либо другой активной культурой).


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

Чтобы рассматривать их как литералы, вам нужно использовать встроенное цитирование ; например, / будет указан как '/', '"/" или \/

Чтобы продемонстрировать не буквальное толкование:

PS> [datetime]::ParseExact('6.2019','M/yyyy', [cultureinfo] 'de-DE')

Saturday, June 1, 2019 12:00:00 AM

Обратите внимание, как / соответствовал соответствующему культуре разделителю даты, ..

Хотя подходящие для культуры разделители всегда используются при форматировании output , во время синтаксического анализа - в порядке любезности - интерпретация литерал / и : используется как резервный механизм:

# Works too - "/" is also recognized as a literal.
PS> [datetime]::ParseExact('6/2019','M/yyyy', [cultureinfo] 'de-DE')

Saturday, June 1, 2019 12:00:00 AM
1 голос
/ 01 июня 2019

Попробуйте один из них.

($stringToDatetime1 = '5/29/2019 8:46:47 PM' | Get-Date)
Wednesday, May 29, 2019 8:46:47 PM

($stringToDatetime2 = [DateTime]::ParseExact('5/29/2019 8:46:47 PM','M/d/yyyy h:mm:ss tt',$null))
Wednesday, May 29, 2019 8:46:47 PM

($stringToDatetime3 = [Datetime]'5/29/2019 8:46:47 PM')
Wednesday, May 29, 2019 8:46:47 PM

Кстати, эта ошибка полностью задокументирована здесь:

PowerShell [DateTime] выдает ошибку «Строка не была распознана как действительный DateTime».

0 голосов
/ 01 июня 2019
PS /Users/js> [DateTime]'5/29/2019 8:46:47 PM'

Wednesday, May 29, 2019 8:46:47 PM


PS /Users/js> ([DateTime]'5/29/2019 8:46:47 PM').gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DateTime                                 System.ValueType
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...