PC Review


Reply
Thread Tools Rate Thread

Check DateTime format

 
 
=?Utf-8?B?RGFuIFM=?=
Guest
Posts: n/a
 
      21st Jul 2004
My application asks the user to enter in a date - in the mm/dd/yyyy format. Is there any quick and easy way to verify the date the user enters is formatted correctly? Right now I'm calling DateTime.Parse() and catching the FormatException but it seems this is a bit inefficient - catching the exception that is. There is some pretty obvious delay while it traces back up the call stack. Is there a better way? Something that returns a bool possibly?

--
Dan S
 
Reply With Quote
 
 
 
 
Shiva
Guest
Posts: n/a
 
      22nd Jul 2004
Hi,

To just check the format you may use regular expressions like
\d{1,2}\/\d{1,2}\/\d{4}. If this validates, use DateTime.Parse() to check
the actual values.


"Dan S" <(E-Mail Removed)> wrote in message
news:2B32202C-A4BF-4FB1-824C-(E-Mail Removed)...
My application asks the user to enter in a date - in the mm/dd/yyyy format.
Is there any quick and easy way to verify the date the user enters is
formatted correctly? Right now I'm calling DateTime.Parse() and catching
the FormatException but it seems this is a bit inefficient - catching the
exception that is. There is some pretty obvious delay while it traces back
up the call stack. Is there a better way? Something that returns a bool
possibly?

--
Dan S


 
Reply With Quote
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      22nd Jul 2004
Dan S <(E-Mail Removed)> wrote:
> My application asks the user to enter in a date - in the mm/dd/yyyy
> format. Is there any quick and easy way to verify the date the user
> enters is formatted correctly? Right now I'm calling DateTime.Parse()
> and catching the FormatException but it seems this is a bit
> inefficient - catching the exception that is. There is some pretty
> obvious delay while it traces back up the call stack. Is there a
> better way? Something that returns a bool possibly?


After the first time, which may involve a delay due to loading
resources, throwing an exception is likely to be very fast - far faster
than a user can actually notice. On my laptop I can throw a hundred
thousand exceptions in a second - I think that's rather more than a
user is likely to enter.

I'm not saying that exceptions are always a nice way to go, but I
wouldn't dismiss them for performance reasons - at least not in this
case.

You can use a regular expression to check the format, of course - but
you may well find that doing so is more expensive than just trying to
parse the date and catching the exception.

You could probably do slightly better with a hard-coded test, something
like:

static readonly char[] LowerBounds = "00/00/1000".ToCharArray();
static readonly char[] UpperBounds = "19/39/2999".ToCharArray();
static bool IsProbablyValidDate(string date)
{
if (date.Length != 10)
{
return false;
}
for (int i=0; i < date.Length; i++)
{
char c=date[i];
if (c < LowerBounds[i] || c > UpperBounds[i])
{
return false;
}
}
return true;
}

That gets rid of *many* invalid dates, but not all - you'll still need
to call DateTime.Parse (or preferrably DateTime.ParseExact) and catch
the potential exception, unless you want to do all the parsing
correctly.

Note that it also requires the leading zeroes for months and days - if
you don't want that, it becomes slightly trickier.

(That only deals with dates in years 1000-2999; if you need to deal
with earlier or later years, change the 7th character in
LowerBounds/UpperBounds.)

Here's a benchmark to compare the three approaches mentioned:

using System;
using System.Windows.Forms; // For MethodInvoker
using System.Text.RegularExpressions;
using System.Globalization;

delegate void DoSomething();

class Test
{
static string[] invalid = {"123123", "wibble", "32/12/3223",
"14/23/1999", "04/35/1992", "02/29/2003"};

static string[] valid = {"12/02/2321", "02/12/2312", "02/29/2004",
"01/30/2000"};

const int Iterations = 100000;

static void Main()
{
Time (new MethodInvoker(TestRegex));
Time (new MethodInvoker(TestHardCoded));
Time (new MethodInvoker(TestNoPreCheck));
}

static void Time(MethodInvoker test)
{
DateTime start = DateTime.Now;
test();
DateTime end = DateTime.Now;

Console.WriteLine ("{0}: {1}", test.Method.Name, end-start);
}

static readonly Regex Expression = new Regex
(@"\d{1,2}\/\d{1,2}\/\d{4}", RegexOptions.Compiled);
static void TestRegex()
{
for (int i=0; i < Iterations; i++)
{
foreach (string x in invalid)
{
if (Expression.IsMatch(x))
{
try
{
DateTime.ParseExact(x, "dd/mm/yyyy",
CultureInfo.InvariantCulture);
throw new Exception("Invalid date passed");
}
catch
{
}
}
}
foreach (string x in valid)
{
if (Expression.IsMatch(x))
{
try
{
DateTime.ParseExact(x, "dd/mm/yyyy",
CultureInfo.InvariantCulture);

}
catch
{
throw new Exception("Valid date failed");
}
}
else
throw new Exception("Valid date failed");
}
}
}

static void TestHardCoded()
{
for (int i=0; i < Iterations; i++)
{
foreach (string x in invalid)
{
if (IsProbablyValidDate(x))
{
try
{
DateTime.ParseExact(x, "dd/mm/yyyy",
CultureInfo.InvariantCulture);

throw new Exception("Invalid date passed");
}
catch
{
}
}
}
foreach (string x in valid)
{
if (IsProbablyValidDate(x))
{
try
{
DateTime.ParseExact(x, "dd/mm/yyyy",
CultureInfo.InvariantCulture);

}
catch
{
throw new Exception("Valid date failed");
}
}
else
throw new Exception("Valid date failed");
}
}
}

static void TestNoPreCheck()
{
for (int i=0; i < Iterations; i++)
{
foreach (string x in invalid)
{
try
{
DateTime.ParseExact(x, "dd/mm/yyyy",
CultureInfo.InvariantCulture);
throw new Exception("Invalid date passed");
}
catch
{
}
}
foreach (string x in valid)
{
try
{
DateTime.ParseExact(x, "dd/mm/yyyy",
CultureInfo.InvariantCulture);
}
catch
{
throw new Exception("Valid date failed");
}
}
}
}

static readonly char[] LowerBounds = "00/00/1000".ToCharArray();
static readonly char[] UpperBounds = "19/39/2999".ToCharArray();
static bool IsProbablyValidDate(string date)
{
if (date.Length != 10)
{
return false;
}
for (int i=0; i < date.Length; i++)
{
char c=date[i];
if (c < LowerBounds[i] || c > UpperBounds[i])
{
return false;
}
}
return true;
}
}

The results on my laptop were:
TestRegex: 00:00:09.3437500
TestHardCoded: 00:00:04.3437500
TestNoPreCheck: 00:00:12.5156250

Changing the regex to require exactly two digits instead of 1 or 2 for
the month and day sped it up very slightly, but not really
significantly.

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
 
Reply With Quote
 
Cor Ligthert
Guest
Posts: n/a
 
      22nd Jul 2004
Hi Dan,

Probably you are using C# because you write so nice your DateTme.Parse().

However when you use VBNet you can use this.
http://msdn.microsoft.com/library/de...afctisdate.asp


Cor

> My application asks the user to enter in a date - in the mm/dd/yyyy

format. Is there any quick and easy way to verify the date the user enters
is formatted correctly? Right now I'm calling DateTime.Parse() and catching
the FormatException but it seems this is a bit inefficient - catching the
exception that is. There is some pretty obvious delay while it traces back
up the call stack. Is there a better way? Something that returns a bool
possibly?
>



 
Reply With Quote
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      22nd Jul 2004
Cor Ligthert <(E-Mail Removed)> wrote:
> Probably you are using C# because you write so nice your DateTme.Parse().
>
> However when you use VBNet you can use this.
> http://msdn.microsoft.com/library/de...ary/en-us/vblr
> 7/html/vafctisdate.asp


In fact, you can use that from within C# as well, if you really want to
(although personally I'd recommend against using it).

You just need to add a reference to the Microsoft.VisualBasic.dll
assembly, and then add

using Microsoft.VisualBasic;

at the top of the source file, then use

Information.IsDate(foo);

However, I very much doubt that that would be any faster than a
straight try/catch round DateTime.ParseExact.

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
 
Reply With Quote
 
Cor Ligthert
Guest
Posts: n/a
 
      22nd Jul 2004
Hi Jon,

I stuffed this row from the message while I was afraid to offend you.

\\\
As Jon often write it can be used in C# as well, when you want maybe he can
than give you the proper code.
///

:-)

Cor

> > Probably you are using C# because you write so nice your

DateTme.Parse().
> >
> > However when you use VBNet you can use this.
> > http://msdn.microsoft.com/library/de...ary/en-us/vblr
> > 7/html/vafctisdate.asp

>
> In fact, you can use that from within C# as well, if you really want to
> (although personally I'd recommend against using it).
>
> You just need to add a reference to the Microsoft.VisualBasic.dll
> assembly, and then add
>
> using Microsoft.VisualBasic;
>
> at the top of the source file, then use
>
> Information.IsDate(foo);
>
> However, I very much doubt that that would be any faster than a
> straight try/catch round DateTime.ParseExact.
>



 
Reply With Quote
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      22nd Jul 2004
Cor Ligthert <(E-Mail Removed)> wrote:
> I stuffed this row from the message while I was afraid to offend you.
>
> \\\
> As Jon often write it can be used in C# as well, when you want maybe he can
> than give you the proper code.
> ///


LOL - certainly no offence taken. I just don't think it's any better to
use the VB function than to write their equivalent in "straight" .NET
code

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
 
Reply With Quote
 
Cor Ligthert
Guest
Posts: n/a
 
      22nd Jul 2004
Jon,

For me is a try catch the same as a late binding, when it is for in advance
catchable error handling, it should be avoided.

However just my opinion.

Cor

> However, I very much doubt that that would be any faster than a
> straight try/catch round DateTime.ParseExact.
>



 
Reply With Quote
 
Cor Ligthert
Guest
Posts: n/a
 
      22nd Jul 2004
> >
> > \\\
> > As Jon often write it can be used in C# as well, when you want maybe he

can
> > than give you the proper code.
> > ///

>
> LOL - certainly no offence taken. I just don't think it's any better to
> use the VB function than to write their equivalent in "straight" .NET
> code
>

When you had not written that "straight" I would not have answered on this.
You mean with this *the not "straight" .Net* the simple basic namespace
without those very well intressing extentions as in the
Microsoft.VisualBasic namespace.

However I agree with you that it is not right to use that function in C#
with the VB namespace. That difficult it cannot be to write it yourself as
your own class.

Cor


 
Reply With Quote
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      22nd Jul 2004
Cor Ligthert <(E-Mail Removed)> wrote:
> For me is a try catch the same as a late binding, when it is for in advance
> catchable error handling, it should be avoided.
>
> However just my opinion.


You seem to make an assumption that the VB function won't have a
try/catch inside it. I suspect that's not the case. A try/catch inside
someone else's method is going to take just as long as a try/catch
inside your own method...

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Check if string has valid DateTime format Magnus.Moraberg@gmail.com Microsoft C# .NET 1 1st Oct 2008 10:50 AM
Convert a latebinded DataTable column's format from DateTime to string (or format the date time value) RSH Microsoft VB .NET 0 6th Dec 2006 03:49 PM
Revert VS 2005 DataSet.GetXML() DateTime Format back to VS 2003 Format? samtilden@gmail.com Microsoft C# .NET 0 8th Jun 2006 11:25 PM
How to check if a string is in a valid DateTime format? =?Utf-8?B?QW5kcmV3?= Microsoft Dot NET Framework Forms 3 13th Feb 2006 07:31 PM
DateTime problem: how to create datetime format hh:mm:ss AM/PM without the date mimi Microsoft C# .NET 1 6th Aug 2004 08:28 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 08:49 PM.