Freigeben über


DateTime.Parse() and DateTime.TryParse() fail in some cases

DateTime.Parse and DateTime.TryParse fail in .Net 2.0 if the user locale date override has a space in it.  Ie: if its something like "M d yyyy".  .Net is getting tripped up over the space (we're working on a fix for SP1/Orcas).

A workaround is to pass the culture without the user overrides as the format specifier.  This works because the non-overridden culture doesn't have the spaces that confuse the tokenizer, and the parser ignores spaces anyway.

 using System;
using System.Globalization;

class Test
{
   static void Main()
  {
       String strDate = "01 Jan 2007";

     Console.WriteLine(strDate);
     Console.WriteLine(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern);
      Console.WriteLine(DateTime.Now.ToShortDateString());

        Console.WriteLine();
        
        DateTime dDate;

     // This works because the user defaults are ignored and the spaces are handled
      // by parse, which ignores spaces anyway.
       dDate = DateTime.Parse(strDate, new CultureInfo(CultureInfo.CurrentCulture.Name, false));
       Console.WriteLine(dDate);

       // This fails because the pattern has a space
       dDate = DateTime.Parse(strDate);
        Console.WriteLine(dDate);
   }
}

The output looks like this (if you set the user override for the date pattern in intl.cpl to "M d yyyy")

 >csc test.cs
>test
01 Jan 2007
M d yyyy
5 10 2007

1 1 2007 12:00:00 AM

Unhandled Exception: System.IndexOutOfRangeException: Index was outside the boun
ds of the array.
   at System.Globalization.DateTimeFormatInfo.InsertHash(TokenHashValue[] hashTa
ble, String str, TokenType tokenType, Int32 tokenValue)
   at System.Globalization.DateTimeFormatInfo.CreateTokenHashTable()
   at System.Globalization.DateTimeFormatInfo.Tokenize(TokenType TokenMask, Toke
nType& tokenType, Int32& tokenValue, __DTString& str)
   at System.__DTString.GetSeparatorToken(DateTimeFormatInfo dtfi)
   at System.DateTimeParse.Lex(DS dps, __DTString& str, DateTimeToken& dtok, Dat
eTimeRawInfo& raw, DateTimeResult& result, DateTimeFormatInfo& dtfi)
   at System.DateTimeParse.TryParse(String s, DateTimeFormatInfo dtfi, DateTimeS
tyles styles, DateTimeResult& result)
   at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyl
es styles)
   at System.DateTime.Parse(String s)
   at Test.Main()

Hopefully this is helpful to people who've run into this problem.  Of course another workaround is just to use a different date seperator.  Of course parsing is generally tricky, particularly if you're asking for the user culture and data.  See Culture data shouldn't be considered stable (except for Invariant) for a list of some of the issues.  In general a calendar control is more reliable when getting data from a user.

'til next time,

Shawn