c# - Check if at least two hours have been spent within a time range, when given two dates -
i have 2 dates , need check if @ least 2 consecutive hours have been spent between times 1am , 5am, within dates.
for example, if datefrom 2014-05-05 17:00:00 , dateto 2014-05-06 6:00:00, means 2 consecutive hours have been spend between 1am , 5am between 2 dates.
the times (1am , 5am) configurable , not hard-coded - thus, represented variables.
this have done far:
//the timefromresidencyrange , timetoresidencyrange 1am , 5am respectively. //they collected 2 `datetimepicker` .net controls. timefromresidencyrange = dtptime1.value; //for testing, 1am (but can time) timetoresidencyrange = dtptime2.value; //for testing, 5am (but can 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; }
as test cases, have carried out following:
iswithinresidencyrange(datetime.parse("2014-05-05 1:00:00"), datetime.parse("2014-05-05 5:00:00"), (double)amountofhours); //true iswithinresidencyrange(datetime.parse("2014-05-05 2:30:00"), datetime.parse("2014-05-05 5:00:00"), (double)amountofhours); //true iswithinresidencyrange(datetime.parse("2014-05-05 1:00:00"), datetime.parse("2014-05-06 17:00:00"), (double)amountofhours); //true iswithinresidencyrange(datetime.parse("2014-05-05 15:00:00"), datetime.parse("2014-05-05 1:59:00"), (double)amountofhours); //false iswithinresidencyrange(datetime.parse("2014-05-05 15:00:00"), datetime.parse("2014-05-05 2:59:00"), (double)amountofhours); //false iswithinresidencyrange(datetime.parse("2014-05-05 15:00:00"), datetime.parse("2014-05-06 3:00:00"), (double)amountofhours); //true iswithinresidencyrange(datetime.parse("26/08/2013 17:17:13"), datetime.parse("26/08/2013 20:20:30"), (double)amountofhours); //false iswithinresidencyrange(datetime.parse("26/08/2013 17:17:13"), datetime.parse("29/08/2013 20:20:30"), (double)amountofhours); //true iswithinresidencyrange(datetime.parse("2014-05-04 1:00:00"), datetime.parse("2014-05-06 5:00:00"), (double)amountofhours); //true iswithinresidencyrange(datetime.parse("2014-05-05 1:00:00"), datetime.parse("2014-05-15 5:00:00"), (double)amountofhours); //true iswithinresidencyrange(datetime.parse("2014-05-05 1:00:00"), datetime.parse("2014-06-05 5:00:00"), (double)amountofhours); //true iswithinresidencyrange(datetime.parse("2014-05-05 3:00:00"), datetime.parse("2014-05-05 5:00:00"), (double)amountofhours); //true iswithinresidencyrange(datetime.parse("2014-05-05 3:00:00"), datetime.parse("2014-05-05 4:59:00"), (double)amountofhours); //false iswithinresidencyrange(datetime.parse("2014-05-05 1:25:00"), datetime.parse("2014-05-05 2:25:00"), (double)amountofhours); //false iswithinresidencyrange(datetime.parse("2014-05-05 1:25:00"), datetime.parse("2014-05-05 3:25:00"), (double)amountofhours); //true
the comments right expected outcome should - within set, 6th 1 failing, suspect others working coincidence - otherwise work, or fail.
does have idea causing it?
thinking problem think can solved lot less logic. having doodled bit , thought adress problem follows;
edit: updated code check possible ranges in dates of given range. edit2: returns number of occurances in given range.
private int iswithinresidencyrange(datetime datefrom, datetime dateto, double consecutivehours){ var dates = new list<datetime>(); (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 within range. return ((to - from).totalhours >= consecutivehours); } }
this check see whether dates entered overlap "wanted range". if set date starts before 1am, check see there atleast 2 hours (or whatever value specify) wanted start given end date.
and if doesn't start before ends after 5am, checks atleast has 2 hours given start wanted end.
if within range, check see total difference in hours greater 2 (or whatever given).
hope explanation clear enough :)
Comments
Post a Comment