检查DateTime格式 [英] Check DateTime format

查看:73
本文介绍了检查DateTime格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序要求用户输入日期 - 格式为mm / dd / yyyy。有没有快速简便的方法来验证用户输入的日期格式是否正确?现在我正在调用DateTime.Parse()并捕获FormatException,但似乎这有点效率低 - 捕获异常。在跟踪调用堆栈时会有一些非常明显的延迟。有没有更好的办法?有可能返回bool的东西吗?


-

Dan S

解决方案

< blockquote>


要检查格式,可以使用正常表达式,例如

\d {1,2} \ / \d { 1,2} \ / \d {4}。如果验证,请使用DateTime.Parse()检查

的实际值。

Dan S <沓** @ discussions.microsoft.com>在消息中写道

新闻:2B ********************************** @ microsof t.com ...

我的应用程序要求用户以mm / dd / yyyy格式输入日期。

有没有快捷简便的方法验证用户输入的日期

格式正确吗?现在我正在调用DateTime.Parse()并且在FormatException中捕获

但似乎这有点效率低 - 捕获

异常。有一些非常明显的延迟,它会追溯到调用堆栈中的
。有没有更好的办法?什么东西可以返回一个布尔

可能?


-

Dan S

Dan S< Da ** @ discussion.microsoft.com>写道:

我的应用程序要求用户输入日期 - 格式为mm / dd / yyyy
。有没有快速简便的方法来验证用户输入的日期格式是否正确?现在我正在调用DateTime.Parse()
并捕获FormatException,但它似乎有点无效 - 捕获异常。当它跟踪调用堆栈时,有一些非常明显的延迟。有更好的方法吗?有可能返回bool的东西吗?




第一次之后,由于加载

资源而导致延迟,抛出异常是可能非常快 - 比用户实际注意到的快得多b / b
。在我的笔记本电脑上,我可以在一秒钟内抛出一百美元的b $ b,000例外情况 - 我认为用户可能会进入的价格超过一美元。


我不是说异常总是一个很好的方法,但是我不会因为性能原因而忽略它们 - 至少在这个

case。


你当然可以使用正则表达式来检查格式 - 但

你可能会发现这样做所以比仅仅尝试解析日期和捕获异常更贵。


你可以用硬编码测试做得更好,有些东西

喜欢:


静态readonly char [] LowerBounds =" 00/00/1000" .ToCharArray();

static readonly char [] UpperBounds =" 19/39/2999" .ToCharArray();

static bool IsProbablyValidDate(字符串日期)

{

if(date.Length!= 10)

{

返回false;

}

for(int i = 0;我< date.Length; i ++)

{

char c = date [i];

if(c< LowerBounds [i] || c> UpperBounds [i])

{

返回false;

}

}

返回true;

}


摆脱*许多*无效日期,但不是全部 - 你仍然需要

调用DateTime.Parse(或者最好是DateTime.ParseExact)并捕获

潜在的异常,除非你想正确地解析所有解析




请注意,它还需要几个月和几天的前导零 - 如果

你不想要它,它会变得有点棘手。

(仅涉及1000-2999年的日期;如果您需要在早年或晚年交易

,请更改

LowerBounds中的第7个字符/ UpperBounds。)


这里是比较上述三种方法的基准:


使用系统;

使用System.Windows.Forms; //对于MethodInvoker

使用System.Text.RegularExpressions;

使用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迭代= 100000;


static void Main()

{

时间(新的MethodInvoker(TestRegex));

时间(新的MethodInvoker(TestHardCoded));

时间(新的MethodInvoker(TestNoPreCheck)) );

}


静态无效时间(MethodInvoker测试)

{

DateTime start = DateTime.Now;

test();

DateTime end = DateTime.Now;


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

}


静态只读Regex表达式=新的正则表达式

(@" \d {1,2} \ / \d {1,2} \ / \d {4}",RegexOptions.Compiled) ;

static void TestRegex()

{

for(int i = 0;我<迭代; i ++)

{

foreach(字符串x无效)

{

if(Expression.IsMatch(x) ))

{

试试

{

DateTime.ParseExact(x," dd / mm / yyyy" ;,

CultureInfo.InvariantCulture);

抛出新的异常(无效的日期传递);

}

catch

{

}

}

}

foreach(字符串x有效)

{

if(Expression.IsMatch(x))

{

try

{

DateTime.ParseExact(x," dd / mm / yyyy",

CultureInfo.InvariantCulture);

}

catch

{

抛出新例外(有效日期失败);

}

}

其他

抛出新的例外(有效日期失败);

}

}

}


static void TestHardCoded()

{

for(int i = 0; i< Iterations; i ++)

{

foreach(字符串x无效)

{

if(IsProbablyValidDate(x))

{

试试

{

DateTime.ParseExact(x," dd / mm / yyyy",

CultureInfo.InvariantCulture);


抛出新的异常(无效的日期传递);

}

catch

{

}

}

}

foreach(字符串x有效)

{

if(IsProbablyValidDate(x))

{

试试

{

DateTime.ParseExact(x," dd / mm / yyyy",

CultureInfo.InvariantCulture);


}

catch

{

抛出新例外(有效日期失败);

}

}

其他

抛出新例外(有效日期失败);

}

}

}


static void TestNoPreCheck()

{

for(int i = 0;我<迭代; i ++)

{

foreach(字符串x无效)

{

尝试

{

DateTime.ParseExact(x," dd / mm / yyyy",

CultureInfo.InvariantCulture);

抛出新的异常(无效的日期已过去);

}

catch

{

}

}

foreach(字符串x有效)

{

尝试

{

DateTime.ParseExact(x," dd / mm / yyyy",

CultureInfo.InvariantCulture);

}

catch

{

抛出新例外(有效日期失败);

}

}

}

}


静态readonly char [] LowerBounds =" 00/00/1000" .ToCharArray();

static readonly char [] UpperBounds =" 19/39/2999" .ToCharArray();

static bool IsProbablyValidDate(字符串日期)

{

if(date.Length!= 10)

{

返回false;

}

for(int i = 0;我< date.Length; i ++)

{

char c = date [i];

if(c< LowerBounds [i] || c> UpperBounds [i])

{

返回false;

}

}

返回true;

}

}


笔记本电脑上的结果是:

TestRegex: 00:00:09.3437500

TestHard编码:00:00:04.3437500

TestNoPreCheck:00:00:12.5156250


更改正则表达式

需要两个数字而不是1或2个月和白天加速非常小,但实际上并不是很好。


-

Jon Skeet - < sk *** @ pobox.com>
http://www.pobox.com/~skeet

如果回复该群组,请不要给我发邮件


你好Dan,


可能你正在使用C#,因为你写得很好你的DateTme.Parse()。


但是当你使用VBNet时你可以使用它。
http://msdn.microsoft.com/library/de...afctisdate.asp

Cor

我的应用程序要求用户以mm / dd / yyyy
格式输入日期。有没有快速简便的方法来验证用户输入的日期

格式正确?现在我正在调用DateTime.Parse()并且在FormatException中捕获

但似乎这有点效率低 - 捕获

异常。有一些非常明显的延迟,它会追溯到调用堆栈中的
。有没有更好的办法?返回bool的东西

可能吗?



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

解决方案

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" <Da**@discussions.microsoft.com> wrote in message
news:2B**********************************@microsof t.com...
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


Dan S <Da**@discussions.microsoft.com> 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 - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


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?



这篇关于检查DateTime格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆