【问题标题】:How to differentiate between DateTime, Date and Time如何区分日期时间、日期和时间
【发布时间】:2014-08-29 03:41:04
【问题描述】:

可以进入 DateTime 变量的日期和时间有三种样式;日期时间、日期或时间。我想区分它们。我该怎么做?

我在 DataGrid 上创建列过滤。根据它是否是三个之一,过滤器将显示 DateTime 选择器或 DatePicker 或 Time 选择器。

【问题讨论】:

  • 在什么意义上区分?如果您只想要日期部分,请使用.Date。如果您只想要时间部分,请使用.TimeOfDay。除此之外,没有区别。
  • 我在 DataGrid 上创建列过滤。根据它是否是三个之一,过滤器将显示 DateTime 选择器或 DatePicker 或 Time 选择器。
  • 你需要知道DateTime变量中存储了什么。没有合理的 100% 可靠的猜测方法。 “0-0-0 1:00”只是时间还是第 0 年的第一次?
  • 我的思路:如果框架没有提供,自己创建。为DateTime.. 创建几个structs,然后从特定DateTime 将数据设置到这些structs。还为 DateTime 创建几个扩展方法,可以帮助您从 DateTime 中获取日期或时间。
  • DateTime 是一个value type,不能继承自(扩展)。您可以创建一个简单的 PCC(纯 C# 类或结构)

标签: c#


【解决方案1】:

这个分类不是结构的一部分。 IOW 没有内置的方法可以做到这一点,因此您可以选择自己喜欢的实现方式。

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

我建议,如果您不将此时间与日期相关联,请选择TimeSpan,让您的生活变得更轻松。但是我认为情况并非如此。

因此,如果时间确实与日期相关联,我建议您只需创建自己的类型,该类型包含 DateTime,加上一个布尔标志来回答您的问题:它只是日期还是日期+时间? .
这很明显,但无论如何我必须这么说:如果您确实采用这种方法 - 封装和隐藏!
如果您将DateTime 公开为字段,最终用户可能会更改日期的时间,期望它变为日期+时间,但标志不会随之而来。所以不要只做一个包装器,而是做你自己的类型,只在内部使用DateTime

【讨论】:

【解决方案2】:

没有绝对的区分方法。 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;
    }
}

【讨论】:

    【解决方案3】:

    检查DateTime 是否具有日期值的唯一方法是将其设为可为空的类型。

    所以是这样的:

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

    除此之外,常规的DateTime 将始终具有日期值(如果不是时间值,或两者兼有)。那是因为它是一个结构,因此它不能为空,除非你“制作”它(通过包装在 Nullable 中,这可以手动完成(Nullable<DateTime>)或更简单 - 通过将? 附加到类型(@987654327 @) 如上所示)。

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

    然后您可以拥有 3 个可为空的属性

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

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

    【讨论】:

    • 基于DateTime创建两个新的变量类型Date和Time怎么样?
    猜你喜欢
    • 2014-11-10
    • 1970-01-01
    • 2020-10-19
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多