2010-01-06 32 views
7

Thông số nhập của tập lệnh của tôi là ngày hoặc số. Dưới đây là một kịch bản mà hoạt động tốt, vì vậy bạn có thể thấy những gì tôi đang cố gắng để làm:Làm cách nào để kiểm tra xem chuỗi có chứa ngày không?

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 
} 

Dưới đây là nỗ lực trước đây của tôi rằng không công việc:

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 
} 

Khi tôi nhập vào một số, ngắt tập lệnh tại dòng phân tích cú pháp ngày. Có vẻ như kiểm tra "của tôi là ngày" của tôi trả về true khi được cấp một số.

Đây có phải là lỗi không? Có phải do thiết kế?

+0

Đó là kịch bản quyền hạn đầu tiên của tôi, vì vậy vui lòng chỉ ra những sai lầm có thể xảy ra của tôi. –

Trả lời

10

Vâng, bạn có thể kiểm tra xem một chuỗi chứa ngày cách nhau bởi dấu (-Như [DateTime]) '. Các vấn đề trong kịch bản ban đầu của tôi là tôi giả định rằng các tham số đầu vào kịch bản là chuỗi. Rõ ràng, tham số số được tự động chuyển đổi thành số nguyên, trừ khi nó được nhập với dấu ngoặc kép. Vì vậy, tôi cần phải viết

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

buộc chuyển đổi số có thể ngược lại thành chuỗi, như Keith trả lời.

Lỗi tương tự áp dụng cho kiểm tra số nguyên của tôi. Tập lệnh không thành công khi được cung cấp “Oct, 3” (không có dấu ngoặc kép). PS có tạo một mảng ở đây không?

Tại sao phân tích cú pháp thất bại khi kiểm tra thành công? Johannes giải thích điều đó. Biểu thức

$date -as [DateTime] 

hướng dẫn PS chuyển đổi đầu vào cho đến nay. Chuyển đổi số có ý nghĩa (ngày 1 là 01 tháng 1, 0001), do đó, nó không thất bại khi đưa ra một số. Biểu thức

[DateTime]::Parse($date) 

phân tích cụ thể một chuỗi, do đó, cho nó một số nguyên không có ý nghĩa và dẫn đến lỗi.

Thật là lãng phí khi tôi sử dụng cả hai. Đầu tiên, tôi chuyển đổi sang ngày trong điều kiện, chỉ để vứt bỏ kết quả. Sau đó, tôi tạo lại kết quả với cú pháp khác nhau.Tôi đang thay đổi điều đó thành

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

Cảm ơn tất cả.

6

Vâng, bạn có thể truyền bất kỳ số nguyên nào đến số DateTime, chỉ đơn giản là vì DateTime chỉ là một số đằng sau hậu trường.

Mỗi DateTime có thuộc tính Ticks là khoảng 100 ns kể từ 0001-01-01. Bạn có thể khởi tạo DateTime bằng những dấu tích đó, mặc dù tôi không tìm thấy sử dụng cho nó cho đến nay.

PS> ([datetime]1234).Ticks 
1234 

Nhưng đó là lý do tại sao bạn có thể truyền số điện thoại tới DateTime và hoạt động. Nó có lẽ chỉ là một ngày rất xa trở lại trong thời gian :-)

Vì vậy, về cơ bản, những gì bạn đang làm bây giờ, i. e. kiểm tra một số đầu tiên, là cách thích hợp để đi khi dàn diễn viên đến DateTime không đủ để giúp bạn xác định xem đó là ngày hay số.

+0

Tôi thích cách tiếp cận này để sử dụng phương pháp [DateTime] :: Parse vì cách tiếp cận này có tác dụng phụ rất tiện lợi. Vì PowerShell sẽ luôn cố gắng truyền bất cứ thứ gì cần cho tham số cho loại cần, bạn có thể gọi hàm này bằng các chuỗi đơn giản theo bất kỳ định dạng ngày giờ địa phương nào: tức là Foo "1: OO PM", Foo "1/1/2012 20:12 " Hy vọng điều này sẽ giúp –

+0

Tôi không theo dõi. Các công trình tương tự cho phân tích DateTime, nó sử dụng văn hóa của chuỗi hiện tại khi phân tích cú pháp chuỗi. Cuối cùng, tôi sẽ mạo hiểm rằng việc chuyển đổi PowerShell sẽ tăng lên vào DateTime.Parse hoặc DateTime.TryParse. Tôi không thấy lý do tại sao họ muốn thực hiện lại mã đó. –

8

Bạn có thể để .NET Framework giúp bạn với điều này:

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

Hoặc bạn có thể để PowerShell làm _all_ việc nâng hạng nặng: chỉ cần sử dụng '[DateTime] $ date' để yêu cầu tham số là kiểu' DateTime'. –

Các vấn đề liên quan