2010-01-06 23 views
7

El parámetro de entrada de mi script es una fecha o un número. Esto es un guión que funciona bien, para que pueda ver lo que yo estoy tratando de hacer:¿Cómo puedo verificar que una cadena contiene una fecha?

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 
} 

Aquí está mi intento previo de que no trabajo:

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 
} 

Cuando ingrese un número, script se rompe en la línea de análisis de fecha. Parece que mi verificación "is is date" devuelve true cuando se le da un número.

¿Es un error? ¿Es por diseño?

+0

Es mi primer script de powershell, así que siéntete libre de señalar mis posibles errores. –

Respuesta

10

sí, se puede comprobar que una cadena contiene la fecha mediante el uso '(-as [Fecha y hora]). El problema en mi script original es que asumí que los parámetros de entrada del script son cadenas. Aparentemente, el parámetro numérico se convierte automáticamente a entero, a menos que se escriba con comillas. Entonces, debería haber escrito

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

forzando la conversión del número posible a la cadena, como lo hace Keith en su respuesta.

El mismo error se aplica a mi comprobación de número entero. La secuencia de comandos falla cuando se le da "Oct, 3" (sin comillas). ¿PS crea una matriz aquí?

¿Por qué falla el análisis cuando la verificación tiene éxito? Johannes explicó eso. Expresión

$date -as [DateTime] 

indica a PS que convierta la entrada a la fecha. La conversión del número tiene sentido (la fecha 1 es el 01 de enero de 0001), por lo que no falla cuando se le da un número. Expresión

[DateTime]::Parse($date) 

analiza específicamente una cadena, por lo que darle un número entero no tiene sentido y conduce a un error.

Fue un desperdicio de mi parte usar ambas cosas, de todos modos. Primero, convierto hasta la fecha en la condición, solo para descartar el resultado. Luego, recreo el resultado con una sintaxis diferente.Estoy cambiando eso a

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

Gracias a todos.

6

Bueno, puede convertir cualquier número entero en DateTime, simplemente porque DateTime es solo un número detrás de las escenas.

Cada DateTime tiene una propiedad Ticks que son intervalos de 100 ns desde 0001-01-01. Puedes inicializar un DateTime con esos tics, aunque hasta ahora no he encontrado un uso para él.

PS> ([datetime]1234).Ticks 
1234 

Pero es por eso que puede emitir un número de DateTime y funciona. Probablemente sea solo una fecha muy atrás en el tiempo :-)

Así que básicamente, lo que estás haciendo ahora, yo. mi. primero verificando un número, es la forma correcta de hacerlo ya que el reparto al DateTime no es suficiente para ayudarlo a determinar si se trata de una fecha o un número.

+0

Prefiero este enfoque para usar el método [DateTime] :: Parse porque este enfoque tiene un efecto secundario muy ingenioso. Dado que PowerShell siempre intentará convertir lo que consiga para un parámetro al tipo que necesita, puede llamar a esta función con cadenas simples en cualquier formato de fecha y hora localizado: es decir Foo "1: OO PM", Foo "1/1/2012 20:12 " Espero que esto ayude –

+0

No sigo. Lo mismo funciona para DateTime parse, utiliza la cultura del hilo actual al analizar la cadena. En última instancia, me atrevería a decir que la conversión de PowerShell termina en DateTime.Parse o DateTime.TryParse. No veo ninguna razón por la cual quieran volver a implementar ese código. –

8

puede dejar que el .NET Framework ayuda que con esto:

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

O podría dejar que PowerShell realice _todos_ los trabajos pesados: simplemente use '[DateTime] $ date' para que el parámetro sea del tipo' DateTime'. –

Cuestiones relacionadas