Входной параметр моего сценария является датой или числом. Вот сценарий, который хорошо работает, таким образом, Вы видите то, что я пытаюсь сделать:
param($date = (Get-Date))
if ($date -match "^\d+$")
{
$date = (Get-Date).AddDays($date)
}
elseif ($date -as [DateTime])
{
$date = [DateTime]::Parse($date)
}
else
{
'You entered an invalid date'
exit 1
}
Вот моя предыдущая попытка, которая не работает:
param($date = (Get-Date))
if ($date -as [DateTime])
{
$date = [DateTime]::Parse($date)
}
elseif ($date -match "^\d+$")
{
$date = (Get-Date).AddDays($date)
}
else
{
'You entered an invalid date'
exit 1
}
Когда я ввел число, сценарий повреждается в строке парсинга даты. Это похоже мой, ", дата" проверка, возвращает true при предоставлении числа.
Действительно ли это - ошибка? Это дизайном?
Да, вы можете проверить, что строка содержит дату, используя '(-как [DateTime])'. Проблема в моем оригинальном скрипте заключается в том, что я предположил, что входные параметры скрипта - это строки. Видимо, числовой параметр автоматически преобразуется в целое число, если только он не набран в кавычках. Поэтому я должен был написать
if ([string]$date -as [DateTime])
, заставляя преобразовывать возможное число обратно в строку, как это делает Кит в своем ответе.
Тот же недостаток применим и к моей проверке целых чисел. Скрипт терпит неудачу при задании "Oct,3" (без кавычек). Создаётся ли здесь массив PS?
Почему при успешной проверке не удаётся выполнить парсинг? Йоханнес объяснил это. Выражение
$date -as [DateTime]
инструктирует PS преобразовывать входные данные в дату. Преобразование числа имеет смысл (дата 1 - 01 января 0001), поэтому при задании числа оно не завершается неудачей. Выражение
[DateTime]::Parse($date)
конкретно разбирает строку, поэтому присвоение ей целого числа не имеет смысла и приводит к ошибке.
В любом случае, с моей стороны было расточительно использовать и то, и другое. Во-первых, я конвертирую в условие дату, только для того, чтобы выбросить результат. Затем я воссоздаю результат с другим синтаксисом. Я меняю его на
$date = $date -as [DateTime];
if (!$date)
{
'You entered an invalid date'
exit 1
}
Спасибо всем.
Ну, вы можете привести любое целое число к DateTime
, просто потому что DateTime
- это всего лишь число за кадром.
Каждое DateTime
имеет свойство Ticks
, которое составляет 100 нс интервалов с 0001-01-01. Вы можете инициализировать DateTime
этими тиками, хотя до сих пор я не нашел им применения.
PS> ([datetime]1234).Ticks
1234
Но именно поэтому вы можете привести число к DateTime
и оно работает. Наверное, это просто дата очень давно :-)
Так что, в принципе, то, что вы сейчас делаете, т.е. сначала проверяете число, это правильный путь, так как приведение к DateTime
не поможет вам определить, дата это или число.
Вы можете позволить .NET-структуре помочь вам с этим:
function ParseDate([string]$date)
{
$result = 0
if (!([DateTime]::TryParse($date, [ref]$result)))
{
throw "You entered an invalid date: $date"
}
$result
}
ParseDate 'June 51, 2001'