Ответ Кирана Патнаюкуни обеспечивает эффективное решение; позвольте мне прояснить, в чем проблема:
Вы, казалось бы, ожидали -Format "MM/dd/yyyy"
, чтобы указать формат разбора ввода ; фактически он форматирует вывод , который затем становится [string]
.
- Однако для значимого сравнения дат необходим экземпляр
[datetime]
.
Ваши аргументы для (подразумеваемого) параметра -Date
((Read-Host ...)
, $csv.updated
) были неявно проанализированы на основе стандартных форматов, распознаваемых текущая культура (System.Globalization.CultureInfo.CurrentCulture
).
Поэтому:
Если ваши аргументы уже правильно распознаются неявным синтаксическим анализом (как вы предполагаете, принимая ответ Кирана), решение состоит в том, чтобы просто удалить -Format
аргументы из вашего кода:
# Parse each input string implicitly, based on the current culture,
# and output a [datetime] instance, which will compare as expected
# with `-gt`
$InputDate = Get-Date (Read-Host -Prompt 'Enter the date')
$CreatedDate = Get-Date $CSV.updated
Если, напротив, вам нужно явно проанализировать строку формата "MM/dd/yyyy"
, чтобы ваши аргументы были распознаны, вызовите. NET метод [datetime]::ParseExact(<string>, <format>[, <culture>])
( System.DateTime.ParseExact
); Например:
# Note: The input string must match the format *exactly*
$InputDate = [datetime]::ParseExact(
(Read-Host -Prompt 'Enter the date'), # input string
"MM/dd/yyyy", # format string
$null # default to the current culture's rules
)
Читайте справочную информацию.
Get-Date
формат ввода и вывода данных:
-Format "MM/dd/yyyy"
не определяет формат ввода , он определяет формат output форматирования строки , который имеет два значения:
String входные данные, переданные во входной параметр -Date
(с которым связан первый позиционный аргумент) - неявно проанализировано как [datetime]
, на основе стандарта форматов строк, распознаваемых текущей культурой [1] ; в действительности за кадром вызывается следующее:
[datetime]::Parse((Read-Host -Prompt 'Enter the date'), [cultureinfo]::CurrentCulture)
- (пропуск
[cultureinfo]::CurrentCulture
в приведенном выше вызове имеет тот же эффект.) - Предупреждение : Когда вы приводите строку к
[datetime]
, это инвариант культура ([cultureinfo]::InvariantCulture
, основано на US-Engli sh) применяется , что часто делает PowerShell для стабильности кода в разных культурах; что командлет, такой как Get-Date
, является , а не культурно-инвариантным, является исторической случайностью, которая не будет исправлена из-за боязни взлома старого кода; см. этот выпуск GitHub для фона. Например, при действующей культуре fr-FR
(по-французски) [datetime] '12/1]
дает 1 декабря (месяц первый), тогда как Get-Date -Date '12/1'
дает 12 января (день первый).
Команда Get-Date
вернет (отформатированную) строку вместо [datetime]
instance ; то есть экземпляр [datetime]
, неявно анализируемый при вводе, форматируется на основе строки формата, переданной в -Format
, на основе правил культуры current ; если $dt
содержит [datetime]
экземпляр, -Format "MM/dd/yyyy"
эквивалентен (обратите внимание, что прямой вызов System.DateTime.ToString()
дает вам возможность указать другая культура, которую -Format
не имеет):
$dt.ToString("MM/dd/yyyy", [cultureinfo]::CurrentCulture)
(по состоянию на PowerShell v7.0), Get-Date
командлет имеет нет поддержку для указания строки формата для input синтаксического анализа.
Как указано, передача строки в -Date
приводит к неявному синтаксическому анализу на основе стандартных форматов даты / времени , распознаваемых современной культурой .
Вам придется вызвать. NET метод [datetime]::ParseExact(<string>, <format>[, <culture>])
(System.DateTime.ParseExact
) , как показано в верхней части.
Если у вас есть экземпляр [datetime]
, вы можете передать его (через -Date
) в Get-Date -Format
, чтобы получить форматированное строковое представление для текущей культуры ; Кроме того, вы можете вызвать .ToString(<format>[, <culture>])
(System.DateTime.ToString
) непосредственно в экземпляре, что также дает вам возможность форматировать для другой культуры .
Что касается Get-Date
ввода и вывода типов данных :
По сути, как ввод передается (уточняется c arguments) определяет способ интерпретации результирующего экземпляра [datetime]
на основе того, как командлет выбирает значение свойства .Kind
экземпляра (Utc
, Local
или Unspecified
) .
Значение свойства .Kind
определяет, какой конкретный c глобальный момент времени, если таковой имеется, представляет экземпляр [datetime]
. Значение .Kind
также может влиять на строковое представление экземпляра, в зависимости от того, какое заданное форматирование c применяется (в частности, включение информации о часовом поясе).
В результате получается экземпляр [datetime]
:
- либо: вывести напрямую (по умолчанию)
- , либо: если передан аргумент
-Format
, является основой для получения запрошенного строкового представления ([string]
).
Get-Date
определяет значение свойства .Kind
следующим образом:
С нет -Date
аргумент, вы получаете экземпляр Local
(представляющий текущую точку во времени)
- (Если строка не также передана
-Date
), используя различные параметры смещения, такие как -Year
и -Day
, также создают экземпляр Local
.
с аргументом -Date
, который уже имеет значение типа [datetime]
, этот экземпляр используется как есть, что означает, что существующее значение свойства .Kind
сохраняется.
С аргументом string -Date
(который анализируется неявно) значение .Kind
будет Unspecified
(представляющим abstract момент времени, без ссылки на определенный c часовой пояс), в том числе в сочетании с такими параметрами, как -Year
.
A цифра c* Аргумент 1296 * -Date
(например, 637165787436900010
) интерпретируется как значение System.DateTime.Ticks
, которое также создает экземпляр Unspecified
.
Примечание : PowerShell [Core] 7.0 представит переключатель -AsUtc
, который придает экземпляру, отформатированному в формате string / to-be-string, вид Utc
; Также обсуждаются переключатели -AsLocal
и -AsUnspecified
(и / или параметр -AsKind <kind>
) - см. этот выпуск GitHub .
[1] Если вход уже является экземпляром [datetime]
, он используется как есть.