Как я проверяю, что строка содержит дату?

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

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 при предоставлении числа.

Действительно ли это - ошибка? Это дизайном?

8
задан buti-oxa 6 January 2010 в 17:22
поделиться

3 ответа

Да, вы можете проверить, что строка содержит дату, используя '(-как [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
}

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

11
ответ дан 5 December 2019 в 06:09
поделиться

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

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

PS> ([datetime]1234).Ticks
1234

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

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

.
6
ответ дан 5 December 2019 в 06:09
поделиться

Вы можете позволить .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'
10
ответ дан 5 December 2019 в 06:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: