Click here to Skip to main content
15,921,577 members
Articles / Programming Languages / C#

C# Date Time Parser

Rate me:
Please Sign up or sign in to vote.
4.72/5 (54 votes)
18 Apr 2012Public Domain4 min read 251.1K   2.5K   158  
Parsing date and (or) time from a string
This is an old version of the currently published article.

Introduction

Once I needed to parse date from internet messages. Those messages were sent by different users, and so could not comply with a single format. They were relatively short, and consisted usually of a sentence, but it was hard to foresee where a date is within a sentence. Thus, the use of DateTime.Parse() was impossible because this method accepts only an exact date presentation string to be parsed. Moreover, later, some date presentations appeared to not be recognized by DateTime.Parse().

What I needed was a C# function like the universal Perl's str2time() or PHP's strtotime(). After some Googling, I was surprised not to find such a code in C#. That's why I wrote the pretty simple class presented here.

Description

The class DateTimeRoutines exposes several date/time parsing methods. The general idea is finding the first instance of the date and (or) time within the passed string and converting it into DateTime.

MethodDescription
TryParseDateTime()Tries to find both a date and a time within the passed string. If a date or time is not found, then it returns false.
TryParseDate()Tries to find a date within the passed string. It always returns the time 0:0:0. If the year of the date was not found, then it accepts, by default, the current year; this rule can be changed by specifying DefaultDate. If a date is not found, then it returns false.
TryParseTime()Tries to find a time within the passed string. If a date previously found in the string is specified as a parameter, then it looks for a time around this date. It always returns the date 1/1/1. If a time is not found, then it returns false.
TryParseDateOrTime()Tries to find a date and/or time within the passed string. If only a time is found, by default, the date is set by today's date; this rule can be changed by specifying DefaultDate. If neither the date nor the time is found, then it returns false.

These methods accept a DateTimeFormat parameter that specifies the recognition format used as preferred in ambivalent instances.

These methods return a ParsedDateTime object. This object describes whether a date (or time) was found within the string and where it was found (if it exists), and also hosts a DateTime structure as a result of parsing.

Also, these methods have derivations that return a DateTime directly instead of ParsedDateTime. The use of the origin methods is preferable though because their output allows knowing whether a date (or time) was really found or if it was constructed by default.

Notice that TryParseDateTime() and TryParseTime() may return different times in the case where the parsed string contains more than one time substring. TryParseDateTime() looks for a time around a date, while TryParseTime() returns a time that was found first.

Usage

The date formats that can be recognized by DateTimeRoutines can be seen in the test strings listed below:

@"Member since:  	10-Feb-2008"
@"Last Update: 18:16 11 Feb '08 "
@"date	Tue, Feb 10, 2008 at 11:06 AM"
@"see at 12/31/2007 14:16:32"
@"sack finish 14:16:32 November 15 2008, 1-144 app"
@"Genesis Message - Wed 04 Feb 08 - 19:40"
@"The day 07/31/07 14:16:32 is "
@"Shipping is on us until December 24, 2008 within the U.S." 
@" 2008 within the U.S. at 14:16:32"
@"5th November, 1994, 8:15:30 pm"
@"7 boxes January 31 , 14:16:32."
@"the blue sky of Sept  30th  2008 14:16:32"
@" e.g. 1997-07-16T19:20:30+01:00"
@"Apr 1st, 2008 14:16:32 tufa 6767"
@"wait for 07/31/07 14:16:32"
@"later 12.31.08 and before 1.01.09"
@"Expires: Sept  30th  2008 14:16:32"
@"Offer expires Apr 1st, 2007, 14:16:32"
@"Expires  14:16:32 January 31."
@"Expires  14:16:32 January 31-st."
@"Expires 23rd January 2010."
@"Expires January 22nd, 2010."
@"Expires DEC 22, 2010."

A code sample if you need to get only the date:

C#
string str = @"The last round was June 10, 2005; " +
        @"this time the unbroken record was held.";
DateTimeRoutines.ParsedDateTime pdt;
if (DateTimeRoutines.TryParseDate(str, 
    DateTimeRoutines.DateTimeFormat.USA_DATE, out pdt))
    Console.WriteLine("Date was found: " + pdt.DateTime.ToString());

A code sample if you want to get the date and, if possible, the time:

C#
string str = @"The last round was June 10, 2005; 
        this time the unbroken record was held.";
DateTimeRoutines.ParsedDateTime pdt;
if (DateTimeRoutines.TryParse(str, DateTimeRoutines.DateTimeFormat.USA_DATE, out pdt)
    && pdt.IsDateFound
    )
    Console.WriteLine("Date was found: " + pdt.DateTime.ToString());

A code sample if you want to get only the completely specified date and time:

C#
string str = @"The last round was June 10, 2005 10:30AM; 
        this time the unbroken record was held.";
DateTimeRoutines.ParsedDateTime pdt;
if (DateTimeRoutines.TryParseDateTime(str, 
            DateTimeRoutines.DateTimeFormat.USA_DATE, out pdt))
    Console.WriteLine("Date&time was found: " + pdt.DateTime.ToString());

A sample of usage as a string class extension method in .NET3+ project:

C#
string str = @"The last round was June 10, 2005 10:30AM; 
        this time the unbroken record was held.";
DateTimeRoutines.ParsedDateTime pdt;
if(str.TryParseDateTime(DateTimeRoutines.DateTimeFormat.USA_DATE, out pdt))
    Console.WriteLine("Date&time was found: " + pdt.DateTime.ToString());

.NET Version Consistency

DateTimeRoutines is formed as a .NET 3.5 DLL that provides the above listed parsed methods as extensions for string class. The DLL can be called by .NET 2 code just as well. However, if you want to embed DateTimeRoutines source code into your .NET 2 project, you'll have to remove keyword this from the method parameters.

Conclusion

This code satisfied my needs. I did not want to implement too wide a recognition capability like say, the one provided by Perl's str2time(), because a more wide recognition means a higher error rate when the parser tries to find a date/time within any part of the passed string.

Nevertheless, DateTimeRoutines seems to be capable of recognizing the usual formats which can be found in a correspondence. If you find some prevalent date/time format that is not recognized, please let me know, and if I have time, I'll try to update the code.

The Code

In the attached code, you can find the DateTimeRoutines project containing:

  • A class DateTimeRoutines that is compiled as a DLL
  • Project Test

The code is licensed as public domain code.

The latest version can be found on SourceForge.

Be happy!

History

  • 11th February, 2009
    • Initial post
  • 14th February, 2009
    • TryParseDateTime() added
  • 18th December, 2009
    • TryParseDate() updated
  • 3rd March, 2010
    • TryParseDate() updated
  • 12th March, 2010
    • locks removed
  • 13th March, 2010
    • Formed as a DLL
    • Methods formed as extensions for string class
    • TryParse() renamed to TryParseDateOrTime()
  • 13th July, 2010
    • Updated source code 
  • 15th May, 2011
    • Fixed 12pm and 12am 
    • Upgraded to C# 4.0 
  • 18th April, 2012
    • Added one more date format;

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Architect CliverSoft (www.cliversoft.com)
Ukraine Ukraine
Sergey is graduated as applied mathematician. He is specialized in custom development including parsing tools, client/server applications.
github: https://github.com/sergeystoyan
site: http://cliversoft.com

Comments and Discussions

Discussions on this specific version of this article. Add your comments on how to improve this article here. These comments will not be visible on the final published version of this article.