如何使用DateTime指定一天中的最新时间


76

我正在使用一个System.DateTime对象来允许用户选择日期范围。用户只能使用第三方日历选择日期(而不是时间),因此我需要自动指定该日期之后应该使用的日期(即:00:00:00或23:59:59)被选中。

在日历选择器将日期存储为DateTime对象之后,如何指定时间?我可以使用这些AddHours, AddMinutes, AddSeconds方法,但是它们是相对于当前时间的,可能不是00:00:00。

startDate将需要有时间是00:00:00,并endDate有一23:59:59时间占到整个天。


一天中的最晚时间是23:59:59.999?
Eppz

您所说的“最新时间”是什么意思?
丹尼尔·怀特

它会尽可能精确地处理(但实际上,秒应该足够多了)
乔·菲利普斯

@ d03boy:您什么意思是“更改时间”?您的意思是将PC时钟设置为该时间吗?
乔恩B

Answers:


105

如果您已经DateTime创建了一个对象,并想用给定日期的11:59:59 PM替换时间,则可以使用该.Date属性获取日期,并将时间设置为00:00:00,然后添加小时,分钟和几秒钟。例如:

var dt = yourDateInstance.Date.AddHours(23).AddMinutes(59).AddSeconds(59);

如果在最近的时间,您的意思是11:59:59 PM,那么这也应该起作用:

var dt = new DateTime(Now.Year, Now.Month, Now.Day, 23, 59, 59);

确实。没有什么表明您必须使用Now.XXX来生成年,月,日,小时,分钟或秒。您可以创建一个DateTime来表示任何给定的时间实例。
Thomas Owens

如果我不确定是否已将其设置为00:00:00怎么办?我可以直接将其设置为时间而不是相对时间吗?
乔·菲利普斯

1
是的,属性.Date返回日期部分,其时间设置为00:00:00。这就是为什么代码说:在添加小时数之前的youDateInstance.Date。
何塞·巴西里奥

很好!感谢您的解释。您可能想将其添加到您可能不会注意到的新手的答案中。
乔·菲利普斯

12
从技术上讲,“一天中的最晚时间”也将具有最大滴答数。
Peter Drier

79

要获取今天的最后时刻:

DateTime d = new DateTime(Now.Year, Now.Month, Now.Day);
d = d.AddDays(1);
d = d.AddTicks(-1);

根据您的修改,我将执行以下操作:

DateTime start = new DateTime(Now.Year, Now.Month, Now.Day);
DateTime end = start.AddDays(1).AddTicks(-1);

// Or - just use end = start.AddDays(1), and use a < for comparison

+1。我在想同样的事情。你们都有内置SO-智能/自动完成功能的特殊键盘吗?
Erich Mirabal,

AddDays(1)会在第二天将其设置为00:00:00吗?
乔·菲利普斯

@ d03boy:完全是。AddDays()将在24小时之后。在这种情况下,在00:00:00.0。如果要在此之前的瞬间,请减去一个刻度。
乔恩B

2
这是假设时间已经设置为00:00:00,这在此处可能不是一个安全的假设。您可以直接设置时间吗?
乔·菲利普斯

1
@ d03boy Jon B通过指定年,月和日来实例化DateTime。这样会将时间设置为0,因此在这种情况下,无需在添加日期之前添加.Date。
元骑士


12

您的问题已经得到了回答,但是恕我直言,更好的方法是不要打扰尝试从范围的末端减去刻度线,秒数或其他数值,并严格使用小于。

所以,如果你想在所有日期包容范围STARTDATE至结束日期,忽略了时间,你可以用C#以下几点:

if ((myDate >= startDate.Date) && (myDate < endDate.Date.AddDays(1)))
{
    // ... it's in the range
}

或在T-SQL中,假设您的@StartDate和@EndDate恰好是午夜,例如:

WHERE SomeDate >= @StartDate AND SomeDate < DATEADD(d,1,@EndDate)

更新

更新了示例,以显示针对评论的包含范围。


IMO,endDate应该仍包含在搜索中。如果我选择6月2日和6月2日作为开始和结束日期怎么办?
乔·菲利普斯

然后,您可以将一天添加到endDate并使用Joe的代码;-)
Meta-Knight

6
DateTime startDate = DateTime.Today;
DateTime stopDate = startDate.AddDays(1).AddTicks(-1);

注意,DateTime.Today返回(来自MSDN)

System.DateTime设置为今天的日期,时间部分设置为00:00:00。

因此,正如其他人指出的那样,添加一天,然后减去最小的时间量(刻度),您将获得当天的最后可能时间。

当然,您可能必须考虑TimeZones之类的问题,具体取决于代码在哪里运行以及用户在哪里。UTC时间可能不错,但是这可能会使您一天(无论哪种方式)都无法完成,具体取决于代码的运行位置。


很高兴您对时区的思考。已经照顾好了。
乔·菲利普斯


2

例如

DateTime.Now.Date.AddDays(1).AddSeconds(-1)

或者AddTicks/AddMilliseconds/AddMinutes...根据您需要的精度。


2

为什么不使用 ToDayEnd()扩展

/// <summary>
    /// Gets the value of the End of the day (23:59)
    /// </summary>
    /// <param name="target"></param>
    /// <returns></returns>
    public static DateTime ToDayEnd(this DateTime target)
    {
        return target.Date.AddDays(1).AddMilliseconds(-1);
    }

但是,如果您真的要说一天的绝对结束,那么AddTicks(-1)是答案。


那是什么图书馆?
Joe Phillips

哦,我的坏..这是我正在使用的库之一。我一直用它这么多,我还以为是Sytem.DateTime的:)部分
AKD

呵呵。认为可能是这样
Joe Phillips

@JoePhillips您可以说这是一个扩展方法,1是静态的,2在关键字this中传递的参数中。

@肯我同意。但这并没有告诉我要使用它需要导入哪个库。它可以是自定义库,也可以位于.net框架中
Joe Phillips

1

yourDateInstance.CloseDate = yourDateInstance.CloseDate.Date.AddDays(1).AddMilliseconds(-1);


1

使用扩展方法

public static DateTime EndOfTheDay(this DateTime date)
{
    return new DateTime(date.Year, date.Month, date.Day).AddDays(1).AddTicks(-1);
}

通过获得一天的开始,这里的结果将为您提供最新的时间-添加一天,然后减去一个勾。其他方法增加了小时,分钟和秒,但是那些依赖于代码功能的解决方案将在23:59:59.000000和23:59:59.999999之间的任何时间引起问题

例如,如果我想知道某个值是否在某个结束日期/时间之前,则其他解决方案的可能性是它们会错过毫秒范围内的值。


非常干净,可重复使用的解决方案。Microsoft在此处提供了有关实现扩展方法的出色文档。
Smitty-Werben-Jager-Manjenson


0

这将给您预期的结果:

DateTime startDate= DateTime.Now.Date;
DateTime endDate= startDate.AddDays(2).Add(new TimeSpan(23, 59, 59));
//startDate: 28/9/2017 0:0:0 endDate: 29/9/2017 23:59:59

1
尽管您的代码确实起作用,但可能会导致问题-即一天结束不是23:59:59,除非您的重要性以秒为单位。但是,如果以DateTime数据的存储方式(毫秒)为单位,则最好将毫秒作为有效值。DateTime也以毫秒值存储在内存中。[从1970年1月1日起的毫秒数]。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.