Ошибка преобразования строки в дату и время в Powershell v5

У меня проблема с двумя строками кода, которые работают не так, как я ожидаю. Дело в том, что объект DateTime преобразуется в string и обратно в DateTime, используя преобразование по умолчанию, без явного указания формата.

$timeString = [DateTime]::Now.ToString() # contains 17.01.2017 20:01:30
$time = [DateTime]$timeString # PS blows with error

Таким образом, в основном он использует формат даты по умолчанию для форматирования строки, но затем, похоже, использует какой-то другой формат для ее обратного анализа. Однако следующая строка кода будет работать:

$otherTime = [DateTime]"01/17/2017 20:01:30" # will get the initial date

Может ли кто-нибудь указать мне на надлежащую документацию по вопросу преобразования типов и почему в этом случае он будет использовать разные форматы для преобразования данных туда и обратно?

Заранее спасибо.


person kosmakoff    schedule 17.01.2017    source источник
comment
Я не смог воспроизвести вашу проблему. Первый блок скрипта работал нормально.   -  person Shawn Esterman    schedule 17.01.2017
comment
Используйте [string][DateTime]::Now или [DateTime]::Now.ToString([CultureInfo]::InvariantCulture).   -  person user4003407    schedule 17.01.2017


Ответы (2)


Разбор дат — это всегда кошмар. Особенно, если вы живете в крошечной части мира, которая называется «за пределами США» :)

В общем, форматирование и синтаксический анализ дат в .NET (и многие другие вещи, такие как сравнение строк) контролируются настройками культуры. В некоторых случаях поведение по умолчанию заключается в использовании текущих настроек культуры. Convert.ToDateTime является одним из них. Если вы посмотрите документацию (Convert. Метод ToDateTime (строка)) говорит:

Если значение не равно null, возвращаемое значение является результатом вызова метода DateTime.Parse для значения с использованием информации о форматировании в объекте DateTimeFormatInfo, который инициализирован для текущего языка и региональных параметров. Аргумент value должен содержать представление даты и времени в одном из форматов, описанных в разделе DateTimeFormatInfo.

Вот почему он преобразуется из вашей локализованной строки даты. В других случаях по умолчанию используется параметр «Неизменная культура», что обычно означает «Настройки для США». Большинство методов перегружены и могут принимать параметр, указывающий язык и региональные параметры, которые следует использовать, но для этого требуется небольшой поиск в документации по .NET.

Эмпирическое правило: не используйте локализованные строки, если они не будут показаны конечному пользователю. Всегда старайтесь найти вариант метода «Инвариантная культура» и используйте его для форматирования и анализа строк. Это избавит вас от многих головных болей.

person Thanassis    schedule 21.01.2017

Вы неявно вызываете Convert.ToDateTime(String), но допустимые форматы этого метода жестко запрограммированы (и не отображаются в списке). Из вашего формата даты вывода я вижу, что вы, вероятно, не в США, и, вероятно, это то, на что ориентировано большинство форматов.

Вместо этого вы можете явно использовать Convert.ToDateTime(String, IFormatProvider) чтобы сообщить ему, какой поставщик формата культуры вы хотите.

[Convert]::ToDateTime($timeString, [System.Globalization.DateTimeFormatInfo]::CurrentInfo)

Я нахожусь в системе США, поэтому я не совсем уверен, будет ли это работать.

Вы также можете использовать [DateTime]::TryParse() или [DateTime]::TryParseExact() чтобы явно указать нужный формат(ы).

person briantist    schedule 17.01.2017
comment
Да, я использую другую культуру, где формат dd.MM.yyyy, а разделитель dot. Я провел дополнительное расследование, и случилось так, что [System.Convert]::ToDateTime("01/18/2017") выдает исключение, а [System.Convert]::ToDateTime("18.01.2017") возвращает действительную дату 18 января. Итак, не похоже, что он вызывает метод Convert.ToDateTime, по крайней мере, без параметров. Может быть, он передает ему инвариантную культуру, кто знает. - person kosmakoff; 18.01.2017
comment
По сути, мой вопрос был не об обходных путях, а о техническом объяснении, почему это работает так, как работает. Может быть, нам нужно где-то зарегистрировать ошибку :) - person kosmakoff; 18.01.2017