Click here to Skip to main content
11,431,483 members (65,740 online)
Click here to Skip to main content

C# Date Time Parser

, 28 Jun 2012 Public Domain
Rate this:
Please Sign up or sign in to vote.
Parsing date and (or) time from a string

Introduction

Once I needed to detect and recognize date and/or time contained in internet messages. Those messages were sent by different users, and so could not comply with certain format. They consisted usually of 1 or 2 sentences and it was impossible to foresee where a date and/or time is within them. Thus, built-in .NET method DateTime.Parse() could not help because this method can parse only strings consisting exactly of a date/time presentation, it cannot look for date/time among text. Moreover, some yet prevalent 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 a date/time parsing class presented here.

Description

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

Method Description
TryParseDateTime() Tries to find both a date and a time within the passed string. If a date or time was not found, it returns false.
TryParseDate() Tries to find a date within the passed string. It always returns time 0Blush | :O Blush | :O . If 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 was not found, 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 date 1/1/1. If a time was not found, it returns false.
TryParseDateOrTime() Tries to find a date and/or time within the passed string. If only a time was found then, by default, date is set by today's date; this rule can be changed by specifying DefaultDate. If neither date nor time was found, it returns false.

These methods accept DateTimeFormat parameter that specifies a 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 was), 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 set by default value.

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

Local and Absolute Time

ParsedDateTime.DateTime is always considered local meaning that it reflects the parsed string literally. If UTC offset or time zone abbreviation indicating that the time is absolute was found in the time string then ParsedDateTime.IsUtcOffsetFound is true and ParsedDateTime.UtcDateTime is UTC date&time. If ParsedDateTime.IsUtcOffsetFound is false, then ParsedDateTime.UtcDateTime should be disregarded as undefined.

Notice that TryParseDate() does not detect time zone

Usage

The date formats that can be recognized by DateTimeRoutines can be seen in the test strings listed below (the complete list of parsed formats can be found in Test project supplied with the code):

@"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 date:

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 date and, if possible, time:

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 completely specified date and time:

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());

A code sample if you want to get UTC date and time:

string str = @"Your program recognizes string : 21 Jun 2010 04:20:19 -0430 blah blah.";
DateTimeRoutines.ParsedDateTime pdt;
if(str.TryParseDateTime(DateTimeRoutines.DateTimeFormat.USA_DATE, out pdt) && pdt.IsUtcOffsetFound) 
Console.WriteLine("UTC date&time was found: " + pdt.UtcDateTime.ToString());

.NET Version Consistency

DateTimeRoutines is formed as a .NET 4 DLL that exposes the parsing 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 more wide recognition capability results in a higher error rate when the parser tries to detect a date/time within any part of a string.

Nevertheless, DateTimeRoutines is capable of recognizing the formats that usually are used in a correspondence. If you find some prevalent date/time format which is not recognized, please let me know and I'll 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
  • 28th June, 2012
    • Added UTC recognition;

License

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

Share

About the Author

Sergey Stoyan
Architect CliverSoft (www.cliversoft.com)
Ukraine Ukraine
Sergey is graduated as applied mathematician. He is specialized in client/server applications, backup systems, data parsing tools, web crawlers and search engines. Work for CliverSoft Co. Favorite languages are C#, C++, Perl

Comments and Discussions

 
GeneralMy vote of 5 Pin
amish kumar4-Dec-12 21:12
memberamish kumar4-Dec-12 21:12 
GeneralRe: My vote of 5 Pin
Sergey Stoyan10-Dec-12 2:51
memberSergey Stoyan10-Dec-12 2:51 
GeneralRe: My vote of 5 Pin
amish kumar10-Dec-12 3:08
memberamish kumar10-Dec-12 3:08 
GeneralRe: My vote of 5 Pin
amish kumar3-Feb-13 19:51
memberamish kumar3-Feb-13 19:51 
GeneralRe: My vote of 5 Pin
Sergey Stoyan11-Apr-14 14:38
memberSergey Stoyan11-Apr-14 14:38 
GeneralRe: My vote of 5 Pin
amish kumar16-Apr-14 20:35
memberamish kumar16-Apr-14 20:35 
GeneralMy vote of 5 Pin
devvvy30-Oct-12 17:06
memberdevvvy30-Oct-12 17:06 
GeneralMy vote of 5 Pin
rctaubert30-Jun-12 10:54
memberrctaubert30-Jun-12 10:54 
GeneralMy vote of 5 Pin
Forogar28-Jun-12 4:37
memberForogar28-Jun-12 4:37 
GeneralRe: My vote of 5 Pin
dave.dolan28-Jun-12 6:59
memberdave.dolan28-Jun-12 6:59 
GeneralRe: My vote of 5 Pin
Sergey Stoyan29-Jun-12 15:30
memberSergey Stoyan29-Jun-12 15:30 
Questionoffset from UTC (like +0300) [modified] Pin
zadront21-Jun-12 21:58
memberzadront21-Jun-12 21:58 
AnswerRe: offset from UTC (like +0300) Pin
Sergey Stoyan25-Jun-12 13:25
memberSergey Stoyan25-Jun-12 13:25 
GeneralRe: offset from UTC (like +0300) Pin
zadront26-Jun-12 22:27
memberzadront26-Jun-12 22:27 
GeneralRe: offset from UTC (like +0300) Pin
Sergey Stoyan28-Jun-12 2:47
memberSergey Stoyan28-Jun-12 2:47 
GeneralRe: offset from UTC (like +0300) Pin
zadront2-Jul-12 2:55
memberzadront2-Jul-12 2:55 
SuggestionSome more formats to add Pin
bbp12317-Apr-12 10:14
memberbbp12317-Apr-12 10:14 
GeneralRe: Some more formats to add Pin
Sergey Stoyan18-Apr-12 0:41
memberSergey Stoyan18-Apr-12 0:41 
GeneralRe: Some more formats to add Pin
bbp12325-Apr-12 12:08
memberbbp12325-Apr-12 12:08 
SuggestionMy vote of 5 - support for cultures Pin
Jani Giannoudis31-Aug-11 0:21
memberJani Giannoudis31-Aug-11 0:21 
GeneralRe: My vote of 5 - support for cultures Pin
Sergey Stoyan31-Aug-11 22:25
memberSergey Stoyan31-Aug-11 22:25 
AnswerRe: My vote of 5 - support for cultures Pin
Jani Giannoudis1-Sep-11 10:40
memberJani Giannoudis1-Sep-11 10:40 
GeneralMy vote of 5 Pin
MBigglesworth7928-Jun-11 1:57
memberMBigglesworth7928-Jun-11 1:57 
GeneralBug with times between 12:00 and 1:00 Pin
dbrenth13-May-11 6:10
memberdbrenth13-May-11 6:10 
GeneralRe: Bug with times between 12:00 and 1:00 [modified] Pin
dbrenth13-May-11 6:21
memberdbrenth13-May-11 6:21 
GeneralRe: Bug with times between 12:00 and 1:00 [modified] Pin
Sergey Stoyan15-May-11 23:10
memberSergey Stoyan15-May-11 23:10 
GeneralRe: Bug with times between 12:00 and 1:00 Pin
dbrenth16-May-11 3:39
memberdbrenth16-May-11 3:39 
GeneralRe: Bug with times between 12:00 and 1:00 Pin
Kanou9217-May-11 0:01
memberKanou9217-May-11 0:01 
GeneralRe: Bug with times between 12:00 and 1:00 Pin
Sergey Stoyan17-May-11 1:07
memberSergey Stoyan17-May-11 1:07 
GeneralRe: Bug with times between 12:00 and 1:00 Pin
Kanou9217-May-11 3:11
memberKanou9217-May-11 3:11 
GeneralMy vote of 5 Pin
dbrenth15-Apr-11 6:40
memberdbrenth15-Apr-11 6:40 
GeneralFacilitate multiple matches Pin
IIsi 50MHz6-Dec-10 12:05
memberIIsi 50MHz6-Dec-10 12:05 
GeneralRe: Facilitate multiple matches Pin
Sergey Stoyan6-Dec-10 12:17
memberSergey Stoyan6-Dec-10 12:17 
GeneralMy vote of 5 Pin
KentuckyEnglishman20-Jul-10 3:36
memberKentuckyEnglishman20-Jul-10 3:36 
QuestionWhat about the other countries ? Pin
Kanou9216-Jul-10 4:54
memberKanou9216-Jul-10 4:54 
AnswerRe: What about the other countries ? Pin
Sergey Stoyan19-Jul-10 0:00
memberSergey Stoyan19-Jul-10 0:00 
GeneralMy vote of 5 Pin
Roger Wright13-Jul-10 17:29
memberRoger Wright13-Jul-10 17:29 
QuestionBug in TryParseDateTime ? Pin
CoperNick7-Jun-10 0:48
memberCoperNick7-Jun-10 0:48 
AnswerRe: Bug in TryParseDateTime ? Pin
Sergey Stoyan7-Jun-10 1:13
memberSergey Stoyan7-Jun-10 1:13 
GeneralRe: Bug in TryParseDateTime ? [modified] Pin
CoperNick7-Jun-10 1:48
memberCoperNick7-Jun-10 1:48 
GeneralRe: Bug in TryParseDateTime ? Pin
CoperNick7-Jun-10 1:59
memberCoperNick7-Jun-10 1:59 
GeneralRe: Bug in TryParseDateTime ? Pin
Sergey Stoyan7-Jun-10 2:11
memberSergey Stoyan7-Jun-10 2:11 
GeneralRe: Bug in TryParseDateTime ? Pin
CoperNick7-Jun-10 3:29
memberCoperNick7-Jun-10 3:29 
GeneralRe: Bug in TryParseDateTime ? Pin
CoperNick7-Jun-10 3:57
memberCoperNick7-Jun-10 3:57 
GeneralRe: Bug in TryParseDateTime ? [modified] Pin
Sergey Stoyan7-Jun-10 4:19
memberSergey Stoyan7-Jun-10 4:19 
Generalgood work Pin
Mohammad Elsheimy12-Mar-10 11:35
memberMohammad Elsheimy12-Mar-10 11:35 
GeneralRe: good work Pin
Sergey Stoyan12-Mar-10 23:46
memberSergey Stoyan12-Mar-10 23:46 
GeneralRe: good work Pin
Mohammad Elsheimy13-Mar-10 3:27
memberMohammad Elsheimy13-Mar-10 3:27 
GeneralRe: good work Pin
Sergey Stoyan13-Mar-10 7:47
memberSergey Stoyan13-Mar-10 7:47 
QuestionPointless locking? Pin
Richard Deeming11-Mar-10 10:50
memberRichard Deeming11-Mar-10 10:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150428.2 | Last Updated 28 Jun 2012
Article Copyright 2009 by Sergey Stoyan
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid