2010-01-06 8 views
7

Le paramètre d'entrée de mon script est une date ou un nombre. Voici un script qui fonctionne très bien, de sorte que vous pouvez voir ce que je suis en train de faire:Comment vérifier qu'une chaîne contient une date?

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 
} 

Voici ma précédente tentative que ne le fait pas travail:

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 
} 

Quand je entrer un numéro, la Le script se brise à la ligne d'analyse de date. Il semble que mon contrôle "is is date" retourne vrai quand on lui donne un nombre.

Est-ce un bug? Est-ce par conception?

+0

C'est mon premier script PowerShell, alors n'hésitez pas à signaler mes erreurs possibles. –

Répondre

10

Oui, vous pouvez vérifier qu'une chaîne contient date à l'aide « (-comme [DateTime]) ». Le problème dans mon script d'origine est que j'ai supposé que les paramètres d'entrée de script sont des chaînes. Apparemment, le paramètre numérique est automatiquement converti en nombre entier, à moins qu'il ne soit tapé avec des guillemets. Donc, j'aurais dû écrire

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

forcer la conversion du nombre possible en chaîne, comme le fait Keith dans sa réponse.

La même erreur s'applique à mon contrôle d'entier. Le script échoue lorsqu'il est donné "Oct, 3" (sans guillemets). Est-ce que PS crée un tableau ici?

Pourquoi l'analyse échoue-t-elle lorsque la vérification réussit? Johannes a expliqué cela. Expression

$date -as [DateTime] 

indique à PS de convertir l'entrée à ce jour. Le nombre de conversion est logique (la date 1 est le 01 janvier 0001), donc il n'échoue pas lorsqu'on lui donne un nombre. Expression

[DateTime]::Parse($date) 

analyse explicitement une chaîne, donc lui donner un entier n'a pas de sens et conduit à une erreur.

C'était inutile pour moi d'utiliser les deux, de toute façon. D'abord, je convertis à ce jour dans la condition, seulement pour jeter le résultat. Ensuite, je recréer le résultat avec une syntaxe différente.Je change cela à

$date = $date -as [DateTime]; 
if (!$date) 
{ 
    'You entered an invalid date' 
    exit 1 
} 

Merci à tous.

6

Eh bien, vous pouvez convertir n'importe quel nombre entier en DateTime, simplement parce que DateTime est juste un nombre dans les coulisses.

Chaque DateTime a une propriété Ticks avec des intervalles de 100 ns depuis 0001-01-01. Vous pouvez initialiser un DateTime avec ces ticks, même si je n'ai pas trouvé d'utilisation jusqu'à présent.

PS> ([datetime]1234).Ticks 
1234 

Mais c'est pourquoi vous pouvez jeter un numéro à DateTime et il fonctionne. C'est probablement juste une date très loin dans le temps :-)

Donc, fondamentalement, ce que vous faites maintenant, je. e. vérifier un nombre d'abord, est la bonne façon d'aller que le casting à DateTime ne suffit pas de vous aider à déterminer si c'est une date ou un nombre.

+0

Je préfère cette approche à l'utilisation de la méthode [DateTime] :: Parse parce que cette approche a un très bon effet secondaire. Puisque PowerShell essayera toujours de convertir tout ce qu'il obtient pour un paramètre au type dont il a besoin, vous pouvez appeler cette fonction avec des chaînes simples dans n'importe quel format datetime localisé: ie Foo "1: OO PM", Foo "1/1/2012 20:12 " J'espère que cela aide –

+0

Je ne suis pas. La même chose fonctionne pour l'analyse de DateTime, elle utilise la culture du thread actuel lors de l'analyse de la chaîne. En fin de compte, je dirais que la conversion PowerShell se termine à DateTime.Parse ou DateTime.TryParse. Je ne vois pas pourquoi ils voudraient réimplémenter ce code. –

8

Vous pouvez laisser vous aider .NET Framework avec ceci:

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

    $result 
} 

ParseDate 'June 51, 2001' 
+0

Ou vous pouvez laisser PowerShell faire le gros du travail: il suffit d'utiliser '[DateTime] $ date' pour exiger que le paramètre soit de type' DateTime'. –

Questions connexes