Как мне проверить, что строка содержит дату? - PullRequest
8 голосов
/ 06 января 2010

Входным параметром моего скрипта является дата или число. Вот скрипт, который отлично работает, поэтому вы можете увидеть, что я пытаюсь сделать:

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
}

Когда я ввожу число, скрипт разбивает строку разбора даты. Похоже, мой чек "is is date" возвращает true, когда ему присваивается число.

Это ошибка? Это по дизайну?

Ответы [ 4 ]

11 голосов
/ 07 января 2010

Да, вы можете проверить, что строка содержит дату, используя ‘(-as [DateTime])’. Проблема в моем оригинальном скрипте состоит в том, что я предполагал, что входные параметры скрипта являются строками. По-видимому, числовой параметр автоматически преобразуется в целое число, если он не набирается в кавычках. Итак, я должен был написать

if ([string]$date -as [DateTime])  

принудительное преобразование возможного числа обратно в строку, как это делает Кит в своем ответе.

Тот же недостаток применим к моей проверке целых чисел. Сценарий завершается неудачно, если задано «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
}

Спасибо всем.

10 голосов
/ 06 января 2010

Вы можете позволить .NET Framework помочь вам в этом:

function ParseDate([string]$date)
{
    $result = 0
    if (!([DateTime]::TryParse($date, [ref]$result)))
    {
        throw "You entered an invalid date: $date"
     }

    $result
}

ParseDate 'June 51, 2001'
6 голосов
/ 06 января 2010

Ну, вы можете привести любое целое число к DateTime просто потому, что DateTime это просто число за кадром.

Каждое DateTime имеет свойство Ticks, которое составляет интервалы 100 нс с 0001-01-01. Вы можете инициализировать DateTime с помощью этих тиков, хотя я до сих пор не нашел для него применения.

PS> ([datetime]1234).Ticks
1234

Но вот почему вы можете привести число к DateTime, и это работает. Это, вероятно, просто свидание очень далеко назад во времени: -)

Так что в основном то, что вы делаете сейчас, я. е. сначала проверять число, это правильный путь, так как приведения к DateTime недостаточно помочь вам определить, является ли это число или число.

0 голосов
/ 13 августа 2018

Это короткая альтернатива:

function isDate([string]$strdate)
{
    [boolean]($strdate -as [DateTime])
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...