C# – Time stamp parsing from the beginning of a string in C#

cdatetimenetparsingtimestamp

I am working on re-writing an existing Java software solution in .NET. At one point, the Java solution reads a time stamp at the beginning of a string, simply like this:

SimpleDateFormat dateFormat = new SimpleDateFormat(timeFormat);
dateFormat.setLenient(false);

try
{
    timeStamp = dateFormat.parse(line);
}
catch (ParseException e)
{
    //...
}

Now I am trying to do the same in C#:

DateTimeFormatInfo dateTimeFormatInfo = new DateTimeFormatInfo();
dateTimeFormatInfo.FullDateTimePattern = format;

try
{
    timeStamp = DateTime.Parse(line, dateTimeFormatInfo);
}
catch (FormatException ex)
{
    //...
}

Both languages work until I add some random text after the time stamp in the line variable. Java will just ignore it, but C# will not allow anything else after the time stamp text in the line.

So while Java is happy to parse "01/01/01 01:01:01,001 Hello World!" as a time stamp, C# is not, because " Hello World!" is not specified in the format string.

However, as I cannot make any statement about what might come after the time stamp inside my strings, I cannot include it in my format string.

Any ideas?

Thank you in advance.

Best Answer

Try this:

Dictionary<string, string> tests = new Dictionary<string,string>()
{
    { "yy/MM/dd HH:mm:ss,fff", "01/01/01 01:01:01,001 Hello World!"},
    { "yyyyMMddHHmmssfff", "2009111615413829403 Hello World!"},
    { "d.M.yyyy H:m:s,fff", "8.10.2009 8:17:26,338 Hello World!" }
};

foreach(KeyValuePair<string, string> test in tests)
{
    string pattern = test.Key;
    string format = test.Value;

    DateTimeFormatInfo dateTimeFormatInfo = new DateTimeFormatInfo();
    dateTimeFormatInfo.FullDateTimePattern = pattern;

    Console.WriteLine("{0} - {1}", pattern, format);
    DateTime timeStamp = DateTime.MinValue;
    if (pattern.Contains(' ')) // approach 1: split and conquer
    {
        format = String.Join(" ", format
            .Split(" ".ToCharArray())
            .Take(pattern.Count(c => c == ' ') + 1));
    }
    else
    {
        format = format.Substring(0, pattern.Length);
    }


    if (!DateTime.TryParseExact(
        format, pattern, dateTimeFormatInfo, 
        DateTimeStyles.AllowWhiteSpaces, out timeStamp))
    {
        Console.WriteLine("\tSomething sad happened");
    }
    else
    {
        Console.WriteLine("\t{0}", timeStamp.ToString(pattern));
    }
}
Console.Read();

Note I don't use DateTime.Parse, since it throws an Exception if String isn't a valid DateTime formatted string.

UPDATE 1: Better input handling, as don't expect an whitespace, but uses pattern length

UPDATE 2: Two previous approach merged into this code; I'm aware about using a single d into test #2, but I don't think we can do anything about it.