Почему PowerShell всегда использует культуру США при приведении к DateTime?

Вчера, пытаясь прочитать CSV, я заметил, что PowerShell, похоже, всегда использует формат даты США при использовании [datetime]"date".

Все мои региональные настройки верны, и [DateTime]::Parse("date") использует формат даты для Великобритании (дд/мм/гггг).

Это ошибка или преднамеренное решение? Если обдуманное решение, то это где-нибудь задокументировано?

PS D:\> [DateTime]"12/10/2012"
10 December 2012 00:00:00

PS D:\> [DateTime]::Parse("12/10/2012")
12 October 2012 00:00:00

(Примечание: я ожидаю, что на компьютере в США эти объекты будут такими же, но не здесь, на моих компьютерах в Великобритании).

Примечание: я не хочу менять формат (это файл из внешнего источника), я не хочу форматировать даты на выходе, я знаю, что могу использовать [DateTime]::Parse(). Вопрос в том, что заканчивается на ? :-)


person Danny Tuppeny    schedule 16.01.2013    source источник


Ответы (2)


Это обдуманное решение. При преобразовании строки в DateTime вы можете использовать либо американский формат Braindead, или ISO 8601 — [datetime]'2012-10-12' отлично работает и намного приятнее для чтения.

Причина, по которой это ограничено и ограничено, заключается в том, что сценарии не должны зависеть от текущей культуры, по крайней мере, для литералов и квази-литералов (например, приведенных строк). Это серьезная проблема при написании надежных пакетных файлов, и вы, конечно, не хотите, чтобы такие же проблемы были в PowerShell.

У Ли Холмса есть объяснение, которое можно считать -официальный, так как он входит/был в команду PowerShell в MS:

Чтобы предотвратить появление в сценариях тонких проблем интернационализации, PowerShell рассматривает [DateTime] '11/26/2007' (константу даты) как языковую функцию — так же, как и [Double] 10.5 (числовую константу). Не во всех культурах используется десятичная точка в качестве разделителя дробей, но языки программирования стандартизировать на нем. Не во всех культурах используется формат en-US DateTime, что приводит к миллионам ошибок интернационализации, когда люди не учитывают влияние запуска своего программного обеспечения в этих культурах.

Что Ли забывает упомянуть, так это то, что я писал ранее, что гораздо более разумный формат ISO 8601 также работает.

К сожалению, никакой документации по этому поводу нет ни в документации PowerShell, ни в Спецификации языка (v2). Тем не менее, существует очень мало доказательств, указывающих на то, что это ошибка.

person Joey    schedule 16.01.2013
comment
Я думал, что это может быть связано с согласованностью в разных регионах, но я не могу найти никакой официальной информации об этом. На самом деле, я думаю, что поведение этих двоих по-разному сбивает с толку. Знаете ли вы какую-либо документацию о том, что ведет себя по-другому? - person Danny Tuppeny; 16.01.2013
comment
Все касты ведут себя так. Например. в моей немецкой локали [double]::Parse('1,2') и [double]'1,2' также дают разные результаты. Как я уже сказал, я бы посчитал это не столько недостатком, поскольку вы никогда не хотите, чтобы скрипт терпел неудачу из-за таких вещей с разными локалями. Использование ::Parse делает вещи явными, как и должно быть в этом случае. На каждом языке. - person Joey; 16.01.2013
comment
Я согласен, что это может иметь смысл (хотя я все еще думаю, что это странно), но я не могу найти никакой официальной информации по этому поводу, и я хотел бы прочитать ее, чтобы увидеть, что еще может не работать, как я ожидаю :( - person Danny Tuppeny; 16.01.2013
comment
(примечание: в данном случае это сценарий для моего собственного использования на моей собственной машине, поэтому я сделал некоторые предположения. Я согласен с тем, что общие сценарии должны быть более явными, и этот вопрос больше о том, является ли это задокументированной функцией, чем о том, как на самом деле обойти это). - person Danny Tuppeny; 16.01.2013
comment
Я попытаюсь найти официальные документы по этому поводу через час или около того. Я помню, по крайней мере, PowerShell Cookbook 2nd ed. упоминая, как typecast ведет себя для дат. - person Joey; 16.01.2013
comment
Ссылка на то, о чем говорит @Joey: leeholmes.com/blog/2009/01/13/ - person CB.; 16.01.2013
comment
Действительно, хорошая находка. Я даже прокомментировал этот пост в блоге... ровно 4 года назад :D. На самом деле я собирался раскопать спецификацию, но Ли Холмс является (или, по крайней мере, был) членом команды PowerShell, поэтому его слово, вероятно, имеет такой же вес, как Рэймонд Чен в истории Windows или Эрик Липперт в C#. - person Joey; 16.01.2013
comment
@Christian Спасибо, я наткнулся на это (мне показал коллега), но я до сих пор не могу найти никакой официальной документации об этом. Наверняка существует? :/ - person Danny Tuppeny; 16.01.2013
comment
Мне не нужны доказательства; дело не в том, что я не доверяю Ли Холмсу. Я просто хотел бы прочитать документы, где это, чтобы увидеть, есть ли другие вещи, которые могут вести себя по-другому. Кажется, это довольно важная вещь, которую нужно знать, так что это должно быть где-то упомянуто в официальном тексте справки? - person Danny Tuppeny; 16.01.2013
comment
Дэнни, я немного осмотрелся, но не смог найти ничего, что можно было бы считать официальным. - person Joey; 16.01.2013

При необходимости вы можете принудительно настроить культуру для одной команды:

PS C:\> [System.Threading.Thread]::CurrentThread.CurrentUICulture = "en-US" ; [System.Threading.Thread]::CurrentThread.CurrentCulture = "en-US"; [DateTime]::Parse("12/10/2012")

Monday, December 10, 2012 12:00:00 AM

PS C:\> [System.Threading.Thread]::CurrentThread.CurrentUICulture = "en-GB" ; [System.Threading.Thread]::CurrentThread.CurrentCulture = "en-GB"; [DateTime]::Parse("12/10/2012")

12 October 2012 00:00:00
person Joachim Otahal    schedule 26.08.2020