如何验证“日期和时间”字符串只包含时间?

7

我有一个单一的字符串变量,存储着可能是完整日期或部分日期的内容:

1)完整日期:2010年12月12日上午12:33

2)部分日期:上午12:33(没有日期字段,只有时间)

我正在尝试找出最佳方法来解析该字符串,以确定字符串是否缺少日期字符串。原因是,如果日期丢失,我的代码将在字符串末尾附加默认日期(例如1900年1月1日)。请注意,时间可能以各种格式显示。

更新-我针对此问题的特定解决方案。

正如所有“帖子”所述,这个问题有多种答案,我最终使用了以下方法,并希望它能帮助其他人*:

public DateTime ProcessDateAndTime(string dateString)
{
    string dateAndTimeString = dateString;

    string[] timeFormats = new string[]
    {
        "hh:mm tt", "hh:mm:ss tt",
        "h:mm tt", "h:mm:ss tt", 
        "HH:mm:ss", "HH:mm", "H:mm"
    };
    // check to see if the date string has a time only
    DateTime dateTimeTemp;
    if (DateTime.TryParseExact(dateString, timeFormats,
        CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.None, out dateTimeTemp))
    {
        // setting date to 01/01/1900
        dateAndTimeString = new DateTime(1900, 1, 1).ToShortDateString() + " " + dateString;
    }

    return DateTime.Parse(dateAndTimeString);
}

*注意:此方法基于一个假设,即在应用程序中仅使用特定数量的时间格式,并且保证传递了正确格式的日期和时间或仅时间字符串(进行预验证以删除垃圾文本)。


1
时间可以以各种格式或整个日期时间字符串的形式出现? - Matt Cofer
1
这是一个新应用程序中的用户输入,还是数据挖掘/现有数据?如果这是一个新应用程序,请不要尝试解决此问题 - 让用户以正确的格式提供数据,并记录您期望以特定格式获取数据。或者给他们提供GUI控件,以便获得正确的数据。 - Merlyn Morgan-Graham
1
Matt - 时间可以有各种格式,例如:上午12:55,12:55:33。 Merlyn - 不幸的是,它是基于现有数据而不是用户输入。 - 5StringRyan
我已经编辑了你的标题。请参考“问题的标题应该包含“标签”吗?”,在那里达成共识是“不应该”。 - John Saunders
8个回答

6

使用

Convert.ToDateTime(string value, IFormatProviderProvider provider)

由于字符串有不同的格式,请根据需要提供不同的格式化程序。

顺序可能是:

  • 仅日期
  • 仅时间
  • 日期和时间

如果转换失败,将抛出格式异常。如果您不想出现异常,请改用Datetime.TryParse,它将返回一个布尔值。

根据字符串的表示方式,您可能需要更多的格式化程序。


3

以下是一种不需要了解所有可能的时间格式的方法:

CultureInfo provider = CultureInfo.CurrentCulture;
DateTime time;
DateTime datetime;
bool isTime = DateTime.TryParse(dateString, provider, DateTimeStyles.NoCurrentDateDefault, out time) 
            && time.Date == DateTime.MinValue.Date
            && DateTime.TryParse(dateString, provider, DateTimeStyles.None, out datetime) 
            && datetime.Date != DateTime.MinValue.Date);

如果字符串只包含时间,则第一个TryParse将日期部分设置为1/1/0001或DateTime.MinValue.Date,第二个TryParse将日期部分设置为当前日期。除非由Doctor Who在时光旅行回到1/1/0001之后运行,否则这将起作用。


我必须说这是一个非常出色的解决方案。它为我提供了很好的帮助。非常感谢! - EricCodebot

3

您可以尝试使用正则表达式来验证字符串,顺便提一下,在这里可以找到用于DateTime验证的好正则表达式:这里


2

这可能不是最好的,但它回答了你的问题:

    string dateString = "9:53AM";
    if (!dateString.Contains('/')))
    {
        dateString = DateTime.Now.ToShortDateString() + " " + dateString;
    }

Convert.ToChar("/")?为什么不直接写 '/' 呢? - as-cii
每天学点新东西.. 我不知道你可以这样做。我改了它。谢谢你的提示。 - Matt Cofer
2
如果应用程序需要在世界多个地区运行,这不是一个很好的想法,因为我们并不都使用“/”来分隔日期。例如,在欧洲的某些地区,2010-12-12是写日期的常见方式。 - DeCaf
没错 - 我的答案可能失败的原因有很多,但它确实回答了问题。Bob2Chiv说时间可能有多种格式,但没有提到日期。我认为了解更多细节,然后编写一些正则表达式可能是最好的方法。 - Matt Cofer
@Matt,我认为你可能是在提到原帖作者:Hans Gruber。 - Bob2Chiv
@Bob2Chiv,是的,我很抱歉。现在已经太晚了,无法编辑和修复它。 :/ - Matt Cofer

2

2
查看字符串的长度会很简单,并且支持多种格式。带日期和时间的字符串肯定比只有时间的字符串要长。然而,如果你的输入可能具有高精度的时间(12:30:30:50:20 vs 12/11/11 12:30)和低精度,则此方法无法使用。
如果您不需要立即知道字符串中的值,只想添加默认日期,则此解决方案是理想的。
例如,如果您支持到秒的时间,那么时间将具有8个或更少的字符,而日期时间将具有9个或更多的字符。

1

你也可以尝试

DateTime aTime;
if (DateTime.TryParse(dateString, CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.NoCurrentDateDefault, out aTime))
{
    //if the there is no date part in the dateString, date will
    // default to Gregorian 1/1/0001
}

1

考虑到时间可能以各种格式出现(12/24小时制),最好使用多个模式,按照预定义的顺序尝试解析每个模式,并在第一个成功时解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接