2009-10-07 41 views
1

例如驗證formatString - Type.ToString(formatString),在C#中有一個內置的規定嗎?

DateTime dateTime = System.DateTime.Now;

//從用戶處獲取formatString,例如formatString =「dddd - d - mmmm」;

//驗證用戶提供的formatStrong。

如果格式字符串是有效

字符串結果=則DateTime.ToString(formatString的);

我知道有一種方法是在格式化時抓住預期,但我想知道是否有.Net爲此目的提供的任何類/方法。

謝謝。

+0

什麼應該算作'有效'的格式字符串? – 2009-10-07 13:29:32

+0

任何在格式化時不會引起預期的東西。 – Naresh 2009-10-07 13:45:26

+0

在Reflector中查看DateTime.ToString(string)的代碼顯示它調用一個'private'方法,它手動檢查格式字符串逐個字符並拋出異常。它看起來很複雜。 – Greg 2009-10-07 13:50:20

回答

1

更新

原來有... DateTime.TryParseExact

+0

如果您強制匹配到特定格式,則使用TryParseExact。 TryParse可能是你在這個例子中尋找的東西。 – Bomlin 2009-10-07 13:24:13

+0

是的,但如果日期不能轉換爲指定的格式,它將返回false。 – James 2009-10-07 13:26:47

+0

這就是當你向用戶返回一條消息,他們輸入的格式無效。 – Bomlin 2009-10-07 13:29:49

2

對不起納爾,真是看錯你最初的帖子。我並不知道DateTime中的任何內容可以執行此操作,但擴展方法可能會有所幫助。這個擴展方法封裝了try/catch塊,所以你不必一直檢查它。現在你可以用一個簡單的if語句來檢查格式。

static void Main(string[] args) 
    { 
     string format = "#"; 

     DateTime myDate = DateTime.Now; 

     if (myDate.ValidateFormat(format)) 
      Console.WriteLine(myDate.ToString(format)); 
     else 
      Console.WriteLine("Bad format"); 

     Console.ReadLine(); 

    } 

    static bool ValidateFormat(this object obj, string format) 
    { 
     try 
     { 
      MethodInfo info = obj.GetType().GetMethod("ToString", new Type[] { format.GetType() }); 
      if (info == null) 
       return false; 
      info.Invoke(obj, new object[] { format }); 
      return true; 
     } 
     catch(Exception e) 
     { 
      Console.WriteLine(e.Message); 
      return false; 
     } 
    } 

此ValidateFormat適用於任何數據類型。唯一的缺點是,擴展是在對象上,這意味着一切都會有這種方法。那些沒有ToString(格式)方法的無效格式報告返回false。

+0

感謝您告訴我:「我不知道DateTime中的任何內容會執行此操作,但擴展方法可能會有所幫助。」 是我想確認的內容。 – Naresh 2009-10-07 14:08:31

+0

爲什麼不把它作爲DateTime類型的擴展方法? – James 2009-10-07 14:29:46

+0

這種方法在格式化時依賴於異常,但是我想驗證(或者知道是否可能)而不實際執行格式化。 – Naresh 2009-10-07 14:33:44

0

如果我正確理解您的方案,您正在設計一個應用程序,用戶可以在其中提供數據轉換的日期格式。你想確保日期格式本身是一個有效的.NET日期格式字符串。

如果是這樣的話,你需要做的是對測試使用DateTime.TryParseExact一個已知的日期值格式字符串,正如其他人所描述:

using System.Globalization; // For CultureInfo & DateTimeStyles  
class MyClass 
{ 
    private bool IsValidDateFormatString(string userSuppliedFormat) 
    { 
     CultureInfo enUS = new CultureInfo("en-US"); 
     DateTime testDate = new DateTime(2009, 10, 1, 12, 0, 0); // Noon on Oct 1st 2009 
     bool result; 

     result = DateTime.TryParseExact(userSuppliedFormat, enUS, DateTimeStyles.None, testDate); 

     return result; 

    }  
} 

這應該得到你想要的東西。如果必要的話,將其添加爲一個擴展方法:

using System.Globalization; 
public static class MyClass 
{ 
    private bool IsValidDateFormat(this Date value) 
    { 
     CultureInfo enUS = new CultureInfo("en-US"); 
     DateTime testDate = new DateTime(2009, 10, 1, 12, 0, 0); // Noon on Oct 1st 2009 
     bool result; 

     result = DateTime.TryParseExact(value, enUS, DateTimeStyles.None, testDate); 
     return result;   
    }  
} 

我不知道我會走那麼遠,但是,因爲它看起來像是你會做非常很少。

+0

我的觀點正確,格式字符串HAS要測試,因此我建議使用TryParseExact方法。然而,看着你的代碼,你可以刪除局部變量結果,直接返回TryParseExact方法的結果:) – James 2009-10-07 17:48:06

+0

使用結果變量是我的一個怪癖;當我在調試器中單步執行代碼時,我發現它們很有用,並且希望在退出函數之前設置一個斷點來查看結果。附加變量的成本可以忽略不計,但在調試時查看它的能力是無價的。 – 2009-10-07 18:26:45

+0

這不是TryParseExact的有效重載。第一個參數必須是包含要轉換的日期和時間的字符串,最後一個參數是解析輸出的out參數。 – Greg 2009-10-07 21:48:34

0

我相信唯一的方法是驗證一個已知的有效日期並捕獲FormatException。類似於Mike Hofer所說的,但撥打TryParseExact將不起作用(請參閱我對他的回答的原因)。

try { 
    DateTime validDateTime = new DateTime(1904, 01, 31, 12, 59, 59); 
    string discarded = validDateTime.ToString(FormatString); 

    return true; 
} 
catch (FormatException) { 
    return false; 
} 
catch (ArgumentOutOfRangeException) { 
    return false; // But really, the developer is an idiot 
} 
相關問題