C# 如何获取一天的开始和结束时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/902789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 01:50:33  来源:igfitidea点击:

How to get the start and end times of a day

c#datetime

提问by David

In my C# app, I pass a string variable that is of format yyyymmdd-yyyymmdd that represents a from and to date. I want to get the start and end times for these dates respectively. Currently I have the below code but was wondering if there was more of an elegant solution?

在我的 C# 应用程序中,我传递了一个字符串变量,该变量的格式为 yyyymmdd-yyyymmdd,表示起始日期和截止日期。我想分别获取这些日期的开始时间和结束时间。目前我有以下代码,但想知道是否有更多优雅的解决方案?

So for pdr = 20090521-20090523 would get "20090521 00:00:00" and "20090523 23:59:59"

所以对于 pdr = 20090521-20090523 将得到“20090521 00:00:00”和“20090523 23:59:59”

private void ValidateDatePeriod(string pdr, out DateTime startDate, 
                                out DateTime endDate)
{
    string[] dates = pdr.Split('-');

    if (dates.Length != 2)
    {
        throw new Exception("Date period is of incorrect format");
    }

    if (dates[0].Length != 8 || dates[1].Length != 8)
    {
        throw new Exception("Split date periods are of incorrect format");
    }

    startDate = DateTime.ParseExact(dates[0] + " 00:00:00", 
        "yyyyMMdd HH:mm:ss", null);
    endDate = DateTime.ParseExact(dates[1] + "23:59:59", 
        "yyyyMMdd HH::mm:ss", null);
}

采纳答案by Tracker1

If you are only worried about .Net precision...

如果您只担心 .Net 精度...

startDate = DateTime.ParseExact(dates[0], "yyyyMMdd");
endDate = DateTime.ParseExact(dates[1], "yyyyMMdd").AddTicks(-1).AddDays(1);

You really don't need to concatenate extra values onto the string for the time portion.

您真的不需要将额外的值连接到时间部分的字符串上。



As an addendum, if you are using this for a query against, for example, a database...

作为附录,如果您使用它来查询例如数据库...

startDate = DateTime.ParseExact(dates[0], "yyyyMMdd");
endDate = DateTime.ParseExact(dates[1], "yyyyMMdd").AddDays(1);

With a query of...

随着...的查询

WHERE "startDate" >= @startDate AND "endDate" < @endDate

Then the precision issues noted in the comments won't really matter. The endDatein this case would not be part of the range, but the outside boundary.

那么评论中提到的精度问题就无关紧要了。在这种情况下,endDate不是范围的一部分,而是外部边界。

回答by Matt Brunell

The DateTimeobject has a property called Datewhich will return just the date portion. (The time portion is defaulted to 12:00 am).

DateTime对象有一个名为的属性Date,该属性将仅返回日期部分。(时间部分默认为凌晨 12:00)。

I would recommend as a more elegant solution (IMHO) that if you want to allow any datetime on the last day, then you add 1 day to the date, and compare to allow times greater than or equal to the start date, but strictly less than the end date (plus 1 day).

我会推荐一个更优雅的解决方案(恕我直言),如果你想在最后一天允许任何日期时间,那么你在日期上添加 1 天,并比较允许时间大于或等于开始日期,但严格小于比结束日期(加 1 天)。

// Calling code.  beginDateTime and endDateTime are already set.
// beginDateTime and endDateTime are inclusive.
// targetDateTime is the date you want to check.
beginDateTime = beginDateTime.Date;
endDateTime = endDateTime.Date.AddDays(1);

if ( beginDateTime <= targetDateTime &&
     targetDateTime < endDateTime )
   // Do something.

回答by Lucas

That's pretty much what I would do, with some small tweaks (really no big deal, just nitpicking):

这几乎是我会做的,有一些小的调整(真的没什么大不了的,只是吹毛求疵):

  • The TryParse()/TryParseExact()methods should be used which return falseinstead of throwing exceptions.
  • FormatExceptionis more specific than Exception
  • No need to check for Length == 8, because ParseExact()/TryParseExact()will do this
  • "00:00:00"and "23:59:59"are not needed
  • return true/falseis you were able to parse, instead of throwing an exception (remember to check value returned from this method!)
  • TryParse()/TryParseExact()方法应使用的返回false,而不是抛出异常。
  • FormatExceptionException
  • 无需检查 Length == 8,因为ParseExact()/TryParseExact()会这样做
  • "00:00:00"并且"23:59:59"不需要
  • return true/false你是否能够解析,而不是抛出异常(记得检查从这个方法返回的值!)

Code:

代码:

private bool ValidateDatePeriod(string pdr, out DateTime startDate, 
                        out DateTime endDate)
{
   string[] dates = pdr.Split('-');

   if (dates.Length != 2)
   {
       return false;
   }

   // no need to check for Length == 8 because the following will do it anyway
   // no need for "00:00:00" or "23:59:59" either, I prefer AddDays(1)

   if(!DateTime.TryParseExact(dates[0], "yyyyMMdd", null, DateTimeStyles.None, out startDate))
      return false;

   if(!DateTime.TryParseExact(dates[1], "yyyyMMdd", null, DateTimeStyles.None, out endDate))
      return false;

   endDate = endDate.AddDays(1);
   return true;
}

回答by Andrei R?nea

You could define two extension methods somewhere, in a utility class like so :

您可以在某个实用程序类中的某处定义两个扩展方法,如下所示:

public static DateTime EndOfDay(this DateTime date)
{
    return new DateTime(date.Year, date.Month, date.Day, 23, 59, 59, 999);
}

public static DateTime StartOfDay(this DateTime date)
{
    return new DateTime(date.Year, date.Month, date.Day, 0, 0, 0, 0);
}

And then use them in code like so :

然后像这样在代码中使用它们:

public DoSomething()
{
    DateTime endOfThisDay = DateTime.Now.EndOfDay();
}

回答by anar khalilov

I am surprised to see how an incorrect answerreceived so many upvotes:

我很惊讶地看到一个不正确的答案如何获得如此多的赞成:

Wrong value

错误的值

The correct version would be as follows:

正确的版本如下:

public static DateTime StartOfDay(this DateTime theDate)
{
    return theDate.Date;
}

public static DateTime EndOfDay(this DateTime theDate)
{
    return theDate.Date.AddDays(1).AddTicks(-1);
}

回答by Chris F Carroll

I think we're doing it wrong. There is no such thing as the end of the day. AddTick(-1)only works under the convention that there are no time intervals smaller than a tick. Which is implementation dependent. Admittedly the question comes with a reference implementation, namely the .Net Framework DateTimeclass, but still we should take this as a clue that the function we really want is not EndOfDay()but StartOfNextDay()

我认为我们做错了。没有一天结束这样的事情。AddTick(-1)仅在没有时间间隔小于刻度的约定下有效。这取决于实现。诚然,这个问题带有一个参考实现,即.Net框架DateTime类,但我们仍然要以此为线索,我们真正想要的功能不是EndOfDay(),但StartOfNextDay()

public static DateTime StartOfNextDay(this DateTime date)
{
    return date.Date.AddDays(1);
}

回答by Leon van Wyk

I use the following in C#

我在 C# 中使用以下内容

public static DateTime GetStartOfDay(DateTime dateTime)
{
    return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 0, 0, 0, 0);
}
public static DateTime GetEndOfDay(DateTime dateTime)
{
    return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59, 999);
}

Then in MS SQL I do the following:

然后在 MS SQL 中,我执行以下操作:

if datepart(ms, @dateEnd) = 0
   set @dateEnd = dateadd(ms, -3, @dateEnd)

This will result in MS SQL time of 23:59:59.997 which is the max time before becoming the next day.

这将导致 MS SQL 时间为 23:59:59.997,这是成为第二天之前的最长时间。

You could simply use:

你可以简单地使用:

new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59, 999);

Which will work in MS SQL, but this is not as accurate in .Net side.

这将在 MS SQL 中工作,但这在 .Net 方面并不准确。

回答by Ricardo Mu?oz

For SQL Server (version 2008 R2 tested) this ranges works.

对于 SQL Server(经测试的 2008 R2 版),此范围有效。

StarDate '2016-01-11 00:00:01.990' EndDate '2016-01-19 23:59:59.990'

StarDate '2016-01-11 00:00:01.990' EndDate '2016-01-19 23:59:59.990'

Seems like ticks is greater that the last second of day and automatically round to next day. So i test and works, i made a dummy table with two dates for check what values is sql server catching and inserting in the stored procedure those parameters.

似乎滴答声大于一天的最后一秒并自动舍入到第二天。所以我测试并工作,我制作了一个带有两个日期的虚拟表,用于检查 sql server 捕获哪些值并将这些参数插入到存储过程中。

回答by Solarev Sergey

public static class DateTimeExtension {        
    public static DateTime StartOfTheDay(this DateTime d) => new DateTime(d.Year, d.Month, d.Day, 0, 0,0);
    public static DateTime EndOfTheDay(this DateTime d) => new DateTime(d.Year, d.Month, d.Day, 23, 59,59);
}