如何区分DateTime、Date和Time

本文关键字:Date Time DateTime 何区 | 更新日期: 2023-09-27 18:20:06

DateTime变量中有三种类型的Date和Time;DateTime、Date或Time。我想区分一下它们。我该怎么做?

我正在DataGrid上创建列筛选。过滤器将显示DateTime选取器、DatePicker或Time选取器,具体取决于它是三者之一。

如何区分DateTime、Date和Time

此分类不是结构的一部分。IOW没有内置的方法可以做到这一点,所以由您选择您想要的实现。

有人建议检查TotalSeconds == 0是否是一个很好的解决方案,这可能会让你满意,但我认为应该谨慎使用,因为它是有限的。因为如果你想有一个时间+日期,指向TotalSeconds的日期,那真的是== 0。这种方法会自动将其变成一个日期。

我建议,如果你不把这个时间和约会联系在一起,选择TimeSpan,让你的生活变得更轻松。然而,我认为情况并非如此。

因此,如果时间真的与日期相关,我建议你只需制作自己的类型,包装一个DateTime,再加上一个布尔标志,就可以回答你的问题:它只是日期还是日期+时间
这是显而易见的,但我无论如何都必须这么说:如果你真的采取这种方法-封装&躲起来
如果将DateTime公开为一个字段,则最终用户可能会更改日期的时间,期望它变为日期+时间,但该标志不会随之出现。所以,不要只是制作一个包装器,而是制作自己的类型,只在内部使用DateTime

没有绝对的区分方法。DateTime总是具有日期部分和时间部分。如果仅从一个日期创建DateTime,则时间部分将归零到午夜,但这与实际代表该日期午夜笔划的值没有区别。如果只从一个时间创建DateTime,那么日期部分将等于#1/01/0001#,但这与实际代表新时代第一天时间的值没有区别。

一种选择是假设具有非零时间和日期#1/01/0001#的DateTime仅代表时间,并且具有零时间部分的值仅代表日期。考虑到这一点,您可以添加以下扩展:

public enum DateTimeType
{
    Date,
    Time,
    DateAndTime
}
public static class DateTimeExtensions
{
    private static readonly DateTime ZeroDate = new DateTime(1, 1, 1);
    public static DateTimeType GetDateTimeType(this DateTime value)
    {
        if (value.TimeOfDay == TimeSpan.Zero)
        {
            return DateTimeType.Date;
        }
        if (value.Date == ZeroDate)
        {
            return DateTimeType.Time;
        }
        return DateTimeType.DateAndTime;
    }
}
检查DateTime是否有日期值的唯一方法是将其设为可为null的类型。

这样的东西:

DateTime? dt;
if(dt.HasValue) {
 //has date
 if(dt.Value.TimeOfDay.TotalSeconds == 0) {
   // display datepicker
 } else {
   // display timepicker
 }
} else {
// show date time picker
}

除此之外,常规DateTime将始终具有日期值(如果不是时间值,或者两者都有)。这是因为它是一个结构,因此除非您"使"它为null,否则它是不可为null的(通过包装nullable,这可以手动完成(Nullable<DateTime>),也可以简单得多——通过将?附加到类型(DateTime?),如上所示)。

如果你可以选择使用不同的数据类型(除了DateTime),那么我建议你看看NodaTime(微软应该简单地将其构建到CLR中,并删除他们蹩脚的DateTime结构)。

然后你可以有3个可以为null的属性

LocalDate? Date;
LocalDateTime? DateTime;
LocalTime? Time;

因此,根据哪个道具有价值,可以显示相应的控件。当然,您还需要设置适当的属性,我不确定您是否可以控制该属性。