检查日期时间字符串是否包含时间信息

33

我遇到了一个问题。我从数据库获取了一个日期时间字符串,其中一些日期时间字符串不包含时间。但是根据新的需求,每个日期时间字符串都应该包含时间,如下所示:

1)1980/10/11 12:00:01 2)2010/APRIL/02 17:10:00 3)10/02/10 03:30:34

日期可以采用任何格式,后跟24小时制的时间。

我尝试通过以下代码检测时间是否存在:

string timestamp_string = "2013/04/08 17:30";
DateTime timestamp = Convert.ToDateTime(timestamp_string);
string time ="";

if (timestamp_string.Length > 10)
{
    time = timestamp.ToString("hh:mm");
}
else {
    time = "Time not registered";
}

MessageBox.Show(time);

但这仅适用于无时间日期类型。请问如何检测此日期时间字符串中是否存在时间元素。非常感谢:)

可能匹配 如何验证“日期和时间”字符串是否仅包含时间?

INFO 提供的三个答案由 Arun Selva Kumar,Guru Kara,Patipol Paripoonnanonda 都是正确的并且检查了时间,符合我的目的。但我选择 Guru Kara 的答案,因为他给出的解释简单易懂。非常感谢 :) 非常感谢你们所有人 :)

6个回答

37

日期时间组件TimeOfDay是您所需的。

MSDN说:"与返回表示不带时间部分的日期的DateTime值的Date属性不同,TimeOfDay属性返回表示DateTime值的时间组件的TimeSpan值。"

以下是考虑了所有情况的示例。
由于您确定了格式,因此可以使用DateTime.Parse,否则请使用DateTime.TryParse

var dateTime1 = System.DateTime.Parse("1980/10/11 12:00:00");
var dateTime2 = System.DateTime.Parse("2010/APRIL/02 17:10:00");
var dateTime3 = System.DateTime.Parse("10/02/10 03:30:34");
var dateTime4 = System.DateTime.Parse("02/20/10");

if (dateTime1.TimeOfDay.TotalSeconds == 0) {
    Console.WriteLine("1980/10/11 12:00:00 - does not have Time");
} else {
    Console.WriteLine("1980/10/11 12:00:00 - has Time");
}

if (dateTime2.TimeOfDay.TotalSeconds == 0) {
    Console.WriteLine("2010/APRIL/02 17:10:00 - does not have Time");
} else {
    Console.WriteLine("2010/APRIL/02 17:10:00 - Has Time");
}

if (dateTime3.TimeOfDay.TotalSeconds == 0) {
    Console.WriteLine("10/02/10 03:30:34 - does not have Time");
} else {
    Console.WriteLine("10/02/10 03:30:34 - Has Time");
}

if (dateTime4.TimeOfDay.TotalSeconds == 0) {
    Console.WriteLine("02/20/10 - does not have Time");
} else {
    Console.WriteLine("02/20/10 - Has Time");
}

嘿,谢谢你的回复 :) 我会仔细阅读并回复 :) - Hasitha Shan
15
这种方法对于任何指定时间为午夜的日期时间字符串都会失败;例如对于"2015-02-26T00:00",我期望的结果是"Has Time",但是System.DateTime.Parse("2015-02-26T00:00").TimeOfDay.TotalSeconds评估为0.0。 - Kasper van den Berg
在第一句话中,方法的名称拼错了。我试图编辑它,但是stackoverflow的用户界面说编辑必须至少有六个字符。此外,我同意Kasper van den Berg的观点,认为这个答案不符合要求。 - Tony Pulokas
4
我同意Kasper的看法。这没有考虑到午夜被指定为有效时间。 - Zephryl
我不得不反对-如果总秒数为0,则您知道实际上时间是午夜,对吗? - Isaac Vidrine
我也同意Kasper的观点。如果时间是00:00,TotalSeconds将会给出0的值。这将是一个指示它没有时间属性的指标,而实际上它是有的。 - zerk

9

试试这个,

DateTime myDate;
if (DateTime.TryParseExact(inputString, "dd-MM-yyyy hh:mm:ss", 
    CultureInfo.InvariantCulture, DateTimeStyles.None, out myDate))
{
    //String has Date and Time
}
else
{
    //String has only Date Portion    
}

您可以尝试使用此处列出的其他格式说明符:http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx

嗨,谢谢你的回复 :) 我会尝试这个并且回复 :) - Hasitha Shan
如果字符串不是一个日期,那么你的else语句会给出错误的答案。你需要使用另一个DateTime.TryParseExact方法来处理只有日期格式的字符串。 - Akanksha Gaur
嘿,我尝试了这个,但它总是给出错误消息?你知道为什么吗?string a = "08/04/2013 17:34:00"; DateTime myDate; if (DateTime.TryParseExact(a, "dd/MM/yyyy hh:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out myDate)) { MessageBox.Show("正确"); //字符串包含日期和时间 } else { MessageBox.Show("错误"); //字符串只包含日期部分 } - Hasitha Shan
@Hasitha,您得到了错误cos,您提供的格式说明符不正确,“hh”表示12小时格式中的小时数,请使用指定的格式“HH”。请参考我提供的链接,获取有关日期时间格式的列表! - Arun Selva Kumar

6

Guru KaraPatipol Paripoonnanonda的答案与.net全球化API相结合,结果如下:

bool HasExplicitTime(DateTime parsedTimestamp, string str_timestamp)
{
    string[] dateTimeSeparators = { "T", " ", "@" };
    string[] timeSeparators = {
        CultureInfo.CurrentUICulture.DateTimeFormat.TimeSeparator,
        CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator,
        ":"};

    if (parsedTimestamp.TimeOfDay.TotalSeconds != 0)
        return true;

    string[] dateOrTimeParts = str_timestamp.Split(
            dateTimeSeparators,
            StringSplitOptions.RemoveEmptyEntries);
    bool hasTimePart = dateOrTimeParts.Any(part =>
            part.Split(
                    timeSeparators,
                    StringSplitOptions.RemoveEmptyEntries).Length > 1);
    return hasTimePart;
}

这种方法:

  • 检测到显式的午夜时间(例如“2015-02-26T00:00”);
  • 仅在TimeOfDay指示午夜或没有显式时间时才搜索字符串;
  • 在本地格式中查找显式的午夜时间以及在 .net 可解析的任何格式中查找非午夜时间。

限制:

  • 不会检测非区域性本地格式中的显式午夜时间;
  • 不会检测少于两个部分的显式午夜时间;并且
  • 比 Guru Kara 和 Patipol Paripoonnanonda 的方法更加复杂和繁琐。

1

目前我采用的方法是这样的。它可能不完美,但比将任何12点的日期时间视为没有时间要好得多。我的假设是,如果在末尾添加一个完整的时间规范,它将解析为只有日期,但如果已经有时间组件,则会失败。

我必须假设不存在7个非空格字符或更少的有效日期/时间。似乎“1980/10”可以解析,但“1980/10 01:01:01.001”不能。

我包括了各种测试用例。请随意添加您自己的测试用例,并让我知道它们是否失败。

public static bool IsValidDateTime(this string dateString, bool requireTime = false)
{
    DateTime outDate;
    if(!DateTime.TryParse(dateString, out outDate)) return false;

    if (!requireTime) return true;
    else
    {
        return Regex.Replace(dateString, @"\s", "").Length > 7 
&& !DateTime.TryParse(dateString + " 01:01:01.001", out outDate);
    }
}

public void DateTest()
{
    var withTimes = new[]{
    "1980/10/11 01:01:01.001",
    "02/01/1980 01:01:01.001",
    "1980-01-01 01:01:01.001",
    "1980/10/11 00:00",
    "1980/10/11 1pm",
    "1980-01-01 00:00:00"};

    //Make sure our ones with time pass both tests
    foreach(var date in withTimes){
        Assert.IsTrue(date.IsValidDateTime(), String.Format("date: {0} isn't valid.", date));
        Assert.IsTrue(date.IsValidDateTime(true), String.Format("date: {0} does have time.", date));
    }

    var withoutTimes = new[]{
    "1980/10/11",
    "1980/10",
    "1980/10 ",
    "10/1980",
    "1980 01",
    "1980/10/11 ",
    "02/01/1980",
    "1980-01-01"};

    //Make sure our ones without time pass the first and fail the second
    foreach (var date in withoutTimes)
    {
        Assert.IsTrue(date.IsValidDateTime(), String.Format("date: {0} isn't valid.", date));
        Assert.IsFalse(date.IsValidDateTime(true), String.Format("date: {0} doesn't have time.", date) );
    }

    var bogusTimes = new[]{
    "1980",
    "1980 01:01",
    "80 01:01",
    "1980T01",
    "80T01:01",
    "1980-01-01T01",
    };

    //Make sure our ones without time pass the first and fail the second
    foreach (var date in bogusTimes)
    {
        DateTime parsedDate;
        DateTime.TryParse(date, out parsedDate);
        Assert.IsFalse(date.IsValidDateTime(), String.Format("date: {0} is valid. {1}", date, parsedDate));
        Assert.IsFalse(date.IsValidDateTime(true), String.Format("date: {0} is valid. {1}", date, parsedDate));
    }
}

0
这段代码是否适用于您的使用场景:
bool noTime = _datetimevalue.TimeOfDay.Ticks == 0;
如果DateTime实例中不存在时间组件,则Ticks将为0。

-1
日期和时间总是由一个空格分隔。最简单的方法是:
if (timestamp_string.Split(' ').Length == 2)
{
    // timestamp_string has both date and time
}
else
{
    // timestamp_string only has the date
}

这段代码假设日期始终存在。

如果您想进一步处理(以防日期不存在),可以执行以下操作:

if (timestamp_string.Split(' ')
                    .Select(item => item.Split(':').Length > 1)
                    .Any(item => item))
{
    // this would work for any string format that contains date, for example:
    // 2012/APRIL/03 12:00:05 -> this would work
    // 2013/04/05 09:00:01 -> this would work
    // 08:50:45 2013/01/01 -> this would also work
    // 08:50:50 -> this would also work
}
else
{
    // no date in the timestamp_string at all
}

希望这能帮到你!


嘿,谢谢回复,我会检查并回复 :) - Hasitha Shan
你有机会尝试过吗?请告诉我。 - Pat
嗨,抱歉耽搁了。我已经选择了一个答案,并在问题本身中解释了原因。非常感谢您的帮助 :) 非常感激。 - Hasitha Shan
5
日期时间字符串有时会使用'T'(例如ISO 8601标准格式中的日期)或'@'。已编辑以改进其清晰度。 - Kasper van den Berg
1
正如@KaspervandenBerg所指出的那样,不是所有格式都在日期和时间之间有空格。即使没有时间,格式也可能有空格,例如“Jun 29, 2017”。如果您能够获得数据库中使用的所有日期/时间格式的全面列表,您可能可以使用此技巧。但看起来情况并非如此。 - hypehuman
正如其他人所指出的那样,假设空格是可靠的分隔符可能会在未来给你带来麻烦,参考 https://en.wikipedia.org/wiki/ISO_8601。 - Jeff Mergler

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