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