2009-11-19 59 views
20

以下代碼片段的結果是「12/06/1930 12:00:00」。我如何控制隱含的世紀,使「6月12日30日」變成2030年?DateTime.TryParse世紀控制C#

string dateString = "12 Jun 30"; //from user input 
    DateTime result; 
    DateTime.TryParse(dateString, new System.Globalization.CultureInfo("en-GB"),System.Globalization.DateTimeStyles.None,out result); 
    Console.WriteLine(result.ToString()); 

請預留,就目前而言,這樣一個事實:正確的解決方案是在第一時間正確地指定的日期。

注意:結果與運行代碼的電腦的系統日期時間無關。

答:感謝Deeksy

for (int i = 0; i <= 9; i++) 
    { 
     string dateString = "12 Jun " + ((int)i * 10).ToString(); 
     Console.WriteLine("Parsing " + dateString); 
     DateTime result; 
     System.Globalization.CultureInfo cultureInfo = new System.Globalization.CultureInfo("en-GB"); 
     cultureInfo.Calendar.TwoDigitYearMax = 2099; 
     DateTime.TryParse(dateString, cultureInfo , System.Globalization.DateTimeStyles.None, out result); 
     Console.WriteLine(result.ToString()); 
    } 
+0

的另一個好處這種方法是在數據庫中的時間短於2067頂出,所以設置twodigityearmax到2067很好地工作。 – Nat 2009-11-19 20:47:27

回答

18

這是棘手的,因爲用的TryParse的方式兩位數年的工作是基於您正在使用的CultureInfo對象的日曆屬性的TwoDigitYearMax財產。 (CultureInfo-> Calendar-> TwoDigitYearMax)

爲了使兩位數年份有20個前置符號,您需要手動創建一個CultureInfo對象,該對象具有一個2099設置爲TwoDigitYearMax屬性的Calendar對象。不幸的是,這意味着解析出的任何兩位數字的日期都會有20個前綴(包括98,99等),這可能不是你想要的。

我懷疑你最好的選擇是使用第三方日期分析庫,而不是標準tryparse,它將使用2位數年份的+ 50/-50年規則。 (2位數年份應該在今年前50年和今年50年之間的範圍內)。

或者,您可以覆蓋日曆對象上的ToFourDigitYear方法(它是虛擬的)並使用它來實現-50/+ 50規則。

+0

野田時間ftw! http://noda-time.blogspot.com/ – RCIX 2009-11-19 04:08:13

+0

是的,在這種情況下,他們確實需要將來所有的日期,但很高興知道在需要時放置更復雜的代碼的最佳位置。 – Nat 2009-11-19 20:49:03

+2

雖然答案很古老,但我想知道是否需要爲+/- 50規則使用第三方庫。如果需要+/- 50規則,爲什麼不把'TwoDigitYearMax'設置爲'DateTime.Today。年+ 50'? – grek40 2016-06-17 07:01:04

8

我會寫一個可重複使用的功能:

public static object ConvertCustomDate(string input) 
{ 
    //Create a new culture based on our current one but override the two 
    //digit year max. 
    CultureInfo ci = new CultureInfo(CultureInfo.CurrentCulture.LCID); 
    ci.Calendar.TwoDigitYearMax = 2099; 
    //Parse the date using our custom culture. 
    DateTime dt = DateTime.ParseExact(input, "MMM-yy", ci); 
    return new { Month=dt.ToString("MMMM"), Year=dt.ToString("yyyy") }; 
} 

這裏是我的準日期字符串列表,像

List<string> dates = new List<string>(new []{ 
    "May-10", 
    "Jun-30", 
    "Jul-10", 
    "Apr-08", 
    "Mar-07" 
}); 

掃描過這麼:

foreach(object obj in dates.Select(d => ConvertCustomDate(d))) 
{ 
    Console.WriteLine(obj); 
} 

公告它現在處理30如2030現在而不是1930年...

-1
result = year.ToString().Length == 1 
     || year.ToString().Length == 2 ? "1" 
     : (Convert.ToInt32(year.ToString() 
      .Substring(0, (year.ToString().Length - 2))) + 1).ToString(); 
+0

對於已經確定的答案,這是一個遲到的問題。將來,請儘量格式化,並提供更多的背景知識,爲什麼這個答案比普遍接受的答案更好。 – Claies 2015-02-11 11:11:08

1

我有類似的問題,我用正則表達式解決了它。在你的情況下,它看起來就像是:

private static readonly Regex DateRegex = new Regex(
@"^[0-9][0-9] (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9][0-9]$", 
RegexOptions.Compiled | RegexOptions.ExplicitCapture); 

private static string Beautify(string date) 
{ 
    var match = DateRegex.Match(date); 
    if (match.Success) 
    { 
     // Maybe further checks for correct day 
     return date.Insert("dd-MMM-".Length, "20"); 
    } 

    return date; 
} 
+0

最大的缺點是日期解析是靜態的,因爲意圖是讀取用戶輸入,更靈活的日期解析方法是有用的。 – Nat 2018-02-11 21:39:08