从DateTime中仅获取日期而不包括时间

19
我遇到了这样的情况,我需要从DateTime中只获取Date。
我有一个Nullable的DateTime? StartDate属性用于保存日期值。
我尝试了下面的方法,
var d = Convert.ToDateTime(StartDate).Date;
但是它返回了如 6/22/2006 12:00:00AM 的d。
将其修改为以下方式后,
var d = Convert.ToDateTime(StartDate).Date.ToString("d");
我能够得到d为6/22/2006。但我不想将我的DateTime?转换为String。
有没有一种方法可以在不使用ToString("d")的情况下仅获取Date?

3
DateTime 始终具有时间组件,即使 Date 属性返回的 Date 具有设置为午夜12:00:00的时间。因此,不能获取仅限于 Date 的值,除非将其转换为字符串。但是,你为什么会需要它呢? - Tim Schmelter
不要使用Convert.ToDateTime(StartDate).Date,而要使用StartDate.Value.Date。如果StartDate为null,则两者都会抛出异常,因此您必须确保它不是null。 - Jeppe Stig Nielsen
1
你能解释一下为什么这实际上是个问题吗?有没有特定的原因,为什么你不能只使用 DateTime 并简单地忽略时间部分? - Kjartan
5个回答

33

使用Date属性获取DateTime实例的日期组件:

DateTime dateTimeNow = DateTime.Now;
DateTime datePartOnly = dateTimeNow.Date;    // Return 00/00/0000 00:00:00

使用这种方法,Date属性将返回午夜时刻的日期,因此在这种情况下时间部分将为00:00:00

还有一些其他方法可以仅获取日期部分,但其返回类型将是字符串:

1.) 使用.ToString(string? format),其中format可以是标准格式或自定义格式字符串。

string dateOnlyString = dateTimeNow.ToString("dd/MM/yyyy"); 
//Can also use .ToString("dd-MM-yyyy");

2.) 使用.ToShortDateString()返回与文化有关的日期字符串

string dateOnlyString = dateTimeNow.ToShortDateString(); 
//Returns M/d/yyyy for "en-US" culture
//Returns yyyy/M/d for "ja-JP" culture

参考:这里。


1
也会返回 3/11/2014 12:00:00 AM,这不是 OP 想要的。他想要一个没有时间部分的 DateTime - Tim Schmelter
当然,但你应该在回答中提到这一点。Date不是OP问题的答案(他甚至使用了Convert.ToDateTime(StartDate).Date)。 - Tim Schmelter
1
他已经使用了Date属性,因此简单地要求他使用Date属性的答案是无用的。 - Jeppe Stig Nielsen

16

试试这个:

string x = DateTime.Now.ToShortDateString()

这将把当前日期 (dd/mm/yy) 赋值给字符串变量 x。


这正是我要找的。谢谢。 - i know nothing
它似乎在Xamarin Forms中不存在。虽然在MSDN上建议在系统命名空间下使用。 - Emil

2

C# 10 中,您可以使用 DateOnly

DateOnly date = DateOnly.FromDateTime(DateTime.Now);

2

我认为你的问题有些无意义。

你要求一个没有时间的日期,但是得到了一个有时间的DateTime。不过在大多数情况下,我真的不认为这会成为问题:

如果你创建了一个带有特定日期的DateTime,并将其与另一个日期进行比较,并且这两个日期的时间都设置为午夜,那么你的比较将是有效和正确的。例如:

var yesterday = new DateTime(2014, 3, 10);
var today = new DateTime(2014, 3, 11);
var tomorrow = new DateTime(2014, 3, 12);

比较和排序这些将按您的预期工作,以下也是如此:

if(today == DateTime.Today){
    Console.WriteLine("Today is the day!");
}

换句话说,你可以毫不在意时间部分的存在。

此外,正如您在原始帖子中提到的那样,如果您想确保避免任何时间组件,则可以使用属性Date

// Note the addition of hours, minutes and seconds:
var today = new DateTime(2014, 3, 11, 14, 35, 33); 

if(today == DateTime.Today){
    Console.WriteLine("This never happened...");    
}

if(today.Date == DateTime.Today){
    Console.WriteLine("...But today is still the day!");    
}

-1

DateTime 包含日期和时间。您可以自行决定在特定属性中不使用日期部分,它只是 12:00 AM,但您不会使用它。

在某些情况下,编写自己的类型可能很有用,该类型永远不会包含时间组件。以下是一个起点:

struct Date : IFormattable
{
    readonly DateTime value;
    public Date(DateTime dateAndTime)
    {
        value = dateAndTime.Date;
    }

    public string ToString(string format, IFormatProvider formatProvider)
    {
        return value.ToString(format ?? "d", formatProvider);
    }
    public string ToString(string format)
    {
        return ToString(format, null);
    }
    public string ToString(IFormatProvider formatProvider)
    {
        return ToString(null, formatProvider);
    }
    public override string ToString()
    {
        return ToString(null, null);
    }

    public static implicit operator DateTime(Date date)
    {
        return date.value;
    }
}

value字段确实保存了12 AM的信息,但它是private的,外部无法访问。 ToString()的重载确保除非有其他要求,否则将使用当前区域设置的短日期格式输出Date


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