C# 在给定两个日期的情况下,检查是否在一个时间范围内至少花费了两个小时

C# 在给定两个日期的情况下,检查是否在一个时间范围内至少花费了两个小时,c#,.net,date,datetime,C#,.net,Date,Datetime,我有两次约会,我需要检查在这些日期内,凌晨1点到凌晨5点之间是否有至少连续两个小时的时间 例如,如果dateFrom为2014-05-05 17:00:00,dateTo为2014-05-06 6:00:00,这意味着在这两个日期之间的凌晨1点到凌晨5点之间连续花费了2个小时 时间(凌晨1点和凌晨5点)是可配置的,而不是硬编码的-因此,表示为变量 这就是我到目前为止所做的: //The timeFromResidencyRange and timeToResidencyRange are 1AM

我有两次约会,我需要检查在这些日期内,凌晨1点到凌晨5点之间是否有至少连续两个小时的时间

例如,如果dateFrom为2014-05-05 17:00:00,dateTo为2014-05-06 6:00:00,这意味着在这两个日期之间的凌晨1点到凌晨5点之间连续花费了2个小时

时间(凌晨1点和凌晨5点)是可配置的,而不是硬编码的-因此,表示为变量

这就是我到目前为止所做的:

//The timeFromResidencyRange and timeToResidencyRange are 1AM and 5AM respectively.  
//They are collected from two `DateTimePicker` .NET controls.

timeFromResidencyRange = dtpTime1.Value; //For testing, it is 1AM (but can be any time)
timeToResidencyRange = dtpTime2.Value; //For testing, it is 5AM (but can be any time)

private bool IsWithinResidencyRange(DateTime dateFrom, DateTime dateTo, double consecutiveHours)
{
    var totalDiff = (dateTo - dateFrom).TotalHours;

    if (totalDiff < consecutiveHours)
    {
        return false;
    }

    DateTime desireFromDate = new DateTime();

    if ((dateFrom.TimeOfDay.Hours < timeToResidencyRange.Hour) || (dateFrom.TimeOfDay.Hours == timeToResidencyRange.Hour && dateFrom.TimeOfDay.Minutes == timeToResidencyRange.Minute && dateFrom.TimeOfDay.Seconds == 0))
    {
        desireFromDate = dateFrom;
    }
    else
    {
        desireFromDate = dateFrom.AddDays(1);
    }

    var endOfDesireDate = new DateTime(desireFromDate.Year,
                                       desireFromDate.Month,
                                       desireFromDate.Day, timeToResidencyRange.Hour, timeToResidencyRange.Minute, 0);

    if ((endOfDesireDate - dateFrom).TotalHours < consecutiveHours)
    {
        endOfDesireDate = endOfDesireDate.AddDays(1);
    }
    else
    {
        return true;
    }

    desireFromDate = endOfDesireDate.AddHours(-((timeToResidencyRange - timeFromResidencyRange).TotalHours));

    return (dateTo - desireFromDate).TotalHours >= consecutiveHours;
}
右边的评论是预期的结果——在这一组中,第六个失败了,但我怀疑其他人是巧合——否则他们都会成功,或者全部失败


有人知道是什么原因造成的吗?

考虑到这个问题,我认为可以用更少的逻辑来解决它。经过一点涂鸦和思考,我将解决这个问题如下

编辑:更新代码以检查给定范围日期中的所有可能范围。 EDIT2:现在返回给定范围内发生的次数

private int IsWithinResidencyRange(DateTime dateFrom, DateTime dateTo, double consecutiveHours){

    var dates = new List<DateTime>();
    for (var date = dateFrom.Date; date <= dateTo; date = date.AddDays(1))
        dates.Add(date);

    var occurances = 0;
    foreach (var testDate in dates)
    {
        var testFrom = new DateTime(testDate.Year, testDate.Month, testDate.Day, timeFromResidencyRange.TimeOfDay.Hours, timeFromResidencyRange.TimeOfDay.Minutes,0);
        var testTo = new DateTime(testDate.Year, testDate.Month, testDate.Day, timeToResidencyRange.TimeOfDay.Hours, timeToResidencyRange.TimeOfDay.Minutes, 0);

        if (WithinFrame(dateFrom, dateTo, consecutiveHours, testFrom, testTo))
            occurances++;
    }
    return occurances;

}

private bool WithinFrame(DateTime from, DateTime to, double consecutiveHours, DateTime rangeFrom, DateTime rangeTo)
{
    if (from < rangeFrom)
    {
        return ((to - rangeFrom).TotalHours >= consecutiveHours);
    }
    else if (to > rangeTo)
    {
        return ((rangeTo - from).TotalHours >= consecutiveHours);
    }
    else
    {
        //Is completely within range.
        return ((to - from).TotalHours >= consecutiveHours);
    }
}
private int在ResidencyRange内(DateTime dateFrom、DateTime dateTo、双连续小时){
变量日期=新列表();
对于(变量日期=dateFrom.date;日期=连续小时);
}
否则如果(到>范围到)
{
返回((rangeTo-from).TotalHours>=连续小时);
}
其他的
{
//完全在射程之内。
返回((到-从).TotalHours>=连续小时);
}
}
这将基本上检查输入的日期是否与“通缉范围”重叠。如果设置的日期在凌晨1点之前开始,它会检查从想要的开始到给定的结束日期至少有两个小时(或您指定的任何值)

如果它不是在早上5点之前开始,而是在早上5点之后结束,它会检查从给定的开始到想要的结束至少有两个小时

如果在范围内,检查总小时差是否大于2(或给出的任何值)


希望这个解释足够清楚:)

好吧,不用语法,真相是什么:

A: Period Begin 1AM;
B: Period End   5AM;
a-b range between a Date1 and b Date2
在(A-B)内连续两小时,然后:

if
(
(
a=a+2h
)
及
(b-a)>=2h
)
布尔=真
其他的
bool=false
你能测试一下这个吗

    DateTime A = DateTime.Parse("1900-01-01 01:00:00");
    DateTime B = DateTime.Parse("1900-01-01 05:00:00");
    int amountOfHours = 2;

public bool IsWithinResidencyRange(DateTime a, DateTime b, double c)
{
if ((b - a).TotalHours >= c 
&& (a.TimeOfDay.Hours <= this.B.TimeOfDay.Hours - c 
||  b.TimeOfDay.Hours >= this.A.TimeOfDay.Hours + c))
{
return true;
}
//else
return false;
}
DateTime A=DateTime.Parse(“1900-01-01:00:00”);
DateTime B=DateTime.Parse(“1900-01-01 05:00:00”);
int amountOfHours=2;
公共布尔值不在ResidencyRange(日期时间a、日期时间b、双c)
{
如果((b-a).TotalHours>=c
&&(a.TimeOfDay.Hours=此a.TimeOfDay.Hours+c))
{
返回true;
}
//否则
返回false;
}

您的哪些测试失败了?在这组测试中,第六个测试失败了,但我怀疑其他测试是巧合——否则它们都会工作,或者都会失败。您能添加凌晨1点和凌晨5点变量的声明吗?什么是
timeToResidencyRange
?如果您可以在代码中添加一些注释,解释可能对我们有所帮助的逻辑,那么您俩都是对的,对此表示抱歉。现在编辑它。感谢您提供的信息和代码-我将用一些案例对其进行测试,并让您知道结果是什么:)从逻辑上讲,这或多或少是我提出的,但以更简洁的方式!我在解析时遇到了#7和#8的问题,但我认为这是一种本地格式配置。让我知道它是否有效!我刚刚尝试了上述所有情况-不幸的是,函数返回的结果都是false。由于TimeFromResidentityRange和timeToResidencyRange是从一个只向用户显示时间的DateTimePicker获取的,因此每一个的实际DateTime值都显示为今天的日期,时间为凌晨1点,而今天的日期为凌晨5点。因此,它看起来像总是输入第一个if语句。我怀疑这就是问题所在。可能在我的示例中,我只是将值设置为“2014-05-05凌晨1点”和“2014-05-05凌晨5点”。如果要计算它将是哪一天,那么它将需要更多的代码和逻辑(例如,如果日期跨度超过两天,它会选择哪一天作为凌晨1-5点的间隔)。我已经尝试了代码,但它在以下测试中失败:
IsWithinResidencyRange(DateTime.Parse(“2013-08-26 17:17:13”),DateTime.Parse(“2013-08-26 20:20:30”),(双)amountOfHours);//false
在residencyRange内(DateTime.Parse(“2013-08-26 17:17:13”),“DateTime.Parse”(“2013-08-29 20:20:30”),(双)amountOfHours);//真的
感谢您确认此格式无效。我的格式也失败了。忽略这两行,我得到了预期的结果…我认为:)答案很好!很高兴看到有人考虑逻辑而不是仅仅编写代码。
if
 (
  (
   a <= B - 2h
   OR
   b >= A + 2h
  )
  AND
  (b-a) >= 2h
 )
 bool = true
 else
 bool = false
    DateTime A = DateTime.Parse("1900-01-01 01:00:00");
    DateTime B = DateTime.Parse("1900-01-01 05:00:00");
    int amountOfHours = 2;

public bool IsWithinResidencyRange(DateTime a, DateTime b, double c)
{
if ((b - a).TotalHours >= c 
&& (a.TimeOfDay.Hours <= this.B.TimeOfDay.Hours - c 
||  b.TimeOfDay.Hours >= this.A.TimeOfDay.Hours + c))
{
return true;
}
//else
return false;
}