|
|
Comments and Discussions
|
|
 |

|
THanks for this post.
I can't seem to see how to calculate business hours when starting a session during the day, for example at 10:30AM:
var testPeriod = new CalendarTimeRange(
new DateTime(2012, 4, 5,10,30,0), new DateTime(2012, 4, 10,23,59,59)); //start calc at 10:30 AM
var period = string.Format("period: {0}", testPeriod);
var holidays = new TimePeriodCollection();
double diff = CalculateBusinessHours(testPeriod, holidays);
........
------------------------------
public double CalculateBusinessHours(CalendarTimeRange testPeriod, ITimePeriodCollection holidays = null)
{
CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
filter.AddWorkingWeekDays(); // only working days
filter.CollectingHours.Add(new HourRange(8, 18)); //08:00 - 18:00
.........
pre>
---------------------------------------------------------------------
diff = 30.0 when it should be in fact 40-2.5 = 37.5 business hours.
It would be really appreciate if anyone with experience of this library would be able to point me in the right direction.
Thanks
Barry
|
|
|
|

|
Hi Barry
In this case it's better to use the following method:
public void BusinessHoursSample()
{
TimeRange timeRange = new TimeRange(
new DateTime( 2012, 4, 05, 10, 30, 00 ), new DateTime( 2012, 4, 10, 23, 59, 59 ) );
CalendarDateDiff dateDiff = new CalendarDateDiff();
dateDiff.WorkingHours.Add( new HourRange( 8, 18 ) );
dateDiff.AddWorkingWeekDays();
TimeSpan nonBusinessHours = dateDiff.Difference( timeRange.Start, timeRange.End );
double businessHours = timeRange.Duration.TotalHours - nonBusinessHours.TotalHours;
Console.WriteLine( "business hours: " + businessHours );
}
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder
|
|
|
|
|

|
Hi Barry
For you case you can use the CalendarDateAdd class:
public void CalendarDateAddSample()
{
CalendarDateAdd calendarDateAdd = new CalendarDateAdd();
calendarDateAdd.AddWorkingWeekDays();
calendarDateAdd.ExcludePeriods.Add( new Day( 2012, 4, 9, calendarDateAdd.Calendar ) );
calendarDateAdd.WorkingHours.Add( new HourRange( new Time( 8 ), new Time( 18 ) ) );
DateTime start = new DateTime( 2011, 4, 6, 6, 0, 0 );
TimeSpan offset = new TimeSpan( 40, 0, 0 ); DateTime? end = calendarDateAdd.Add( start, offset );
Console.WriteLine( "end: {0}", end );
}
bc2m wrote: Ps: I really appreciate guys like yourself who help and publish on the web. I try to do the same myself with asp.net, c# etc. Cool
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder
|
|
|
|
|

|
Thank you for the excellent work.
How to exclude holidays from business hours calculations.
public double CalculateBusinessHours()
{
TimeRange timeRange = new TimeRange(new DateTime(2012, 4, 10, 10, 00, 00), new DateTime(2012, 4, 15, 13, 00, 00));
CalendarDateDiff dateDiff = new CalendarDateDiff();
dateDiff.WeekDays.Add(DayOfWeek.Sunday);
dateDiff.WeekDays.Add(DayOfWeek.Monday);
dateDiff.WeekDays.Add(DayOfWeek.Tuesday);
dateDiff.WeekDays.Add(DayOfWeek.Wednesday);
dateDiff.WeekDays.Add(DayOfWeek.Thursday);
dateDiff.WorkingHours.Add(new HourRange(new Time(7, 30), new Time(15, 30)));
var getHolidays = from h in tblHolidays
select h;
foreach (var holiday in getHolidays)
{
DateTime startHoliday = holiday.StartDate;
DateTime endHoliday = holiday.EndDate.AddDays(1);
}
TimeSpan nonBusinessHours = dateDiff.Difference(timeRange.Start, timeRange.End);
double businessHours = timeRange.Duration.TotalHours - nonBusinessHours.TotalHours;
return businessHours;
}
Regards,
Aladdin
|
|
|
|

|
Many thanks alaamh.
What's the source of the tblHolidays and the type of getHolidays (I don't really like the C# type var ).
If your definition of a holiday is a single day, you can exclude it with:
foreach ( ITimePeriod holiday in holidays )
{
DateTime day = holiday.Start;
calendarDateAdd.ExcludePeriods.Add(
new Day( day.Year, day.Month, day.Day, calendarDateAdd.Calendar ) );
}
In case your definition of a holiday is a multi-day range, you can exclude it with:
foreach ( ITimePeriod holiday in holidays )
{
DateTime startDay = holiday.Start;
int days = holiday.Duration.Days;
calendarDateAdd.ExcludePeriods.Add(
new Days( startDay.Year, startDay.Month, startDay.Day, days, calendarDateAdd.Calendar ) );
}
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder
|
|
|
|

|
I had an edge case where there were holidays on Friday 6th April, 2012 and Monday 9th April, 2012. We got a case instruction on the Friday (6th), so I wanted to calculate the case start day (which is 08:00 on Tuesday 10th - excluding hols and weekend). Is there a way to take the theoretical start date/time (Friday 6th, 15:20), add a time period, and then recover the ACTUAL startdate/time of the first available business day, which is after the holidays/weekends. This would make my system really safe and allow me to email the investigators with the earliest "start your investigation" time.
Thanks for your patience and help. For some reason I just can't get my mindset into the library... Will keep working on it as it is going to be increasingly valuable to me.
Barry
PS: I think DaySeeker may be the way to do it? But it is not behaving as expected...
In the code below: If startdate is 2012-4-4 then it says next day is Thursday 5th. If startdate is 2012-4-6 it correctly states first start day is Tuesday 10th. So, is there a way to see if the current date is an available business day (i.e. not a holiday or a W/E). You can't enter 0 as the period, as it then returns Friday 6th when start date is the 6th, which is a holiday...) Thanks. B (wish I wasn't so thick!)
[Test]
public void DaySeekerSample()
{
Day start = new Day(new DateTime(2012, 4, 4,15,2,0));
Console.WriteLine("DaySeeker Start: " + start);
CalendarVisitorFilter filter = new CalendarVisitorFilter();
filter.AddWorkingWeekDays(); // only working days
filter.ExcludePeriods.Add(new Day(2012,4,6));
filter.ExcludePeriods.Add(new Day(2012,4,9));
Console.WriteLine("DaySeeker Holidays: " + filter.ExcludePeriods[0]);
DaySeeker daySeeker = new DaySeeker(filter);
Day day1 = daySeeker.FindDay(start, 1); // same working week
Console.WriteLine("DaySeeker(3): " + day1);
modified 16-Apr-12 10:13am.
|
|
|
|

|
I tried to see if it was a business day using the code you discussed with Alaamh but it doesn't work. Instead of returning 0 hours ('cos it's a holiday), it incorrectly returns ~8 hours, which is the time span from 10-18:00. Sorry, I'm really confused.
startDate = new DateTime(2012,4,6,10,0,0);
var endDate = new DateTime(startDate.Year, startDate.Month, startDate.Day, 17, 59, 58);
TimeRange timeRange = new TimeRange(startDate, endDate);
CalendarDateDiff dateDiff = new CalendarDateDiff();
dateDiff.WorkingHours.Add(new HourRange(8, 18));
dateDiff.AddWorkingWeekDays();
var calendarDateAdd = new CalendarDateAdd();
//exclude this working day from calendar
calendarDateAdd.ExcludePeriods.Add(new Day(2012,4,6,calendarDateAdd.Calendar));
TimeSpan nonBusinessHours = dateDiff.Difference(timeRange.Start, timeRange.End);
//returns 0 which is correct
double businessHours = timeRange.Duration.TotalHours - nonBusinessHours.TotalHours;
//returns 8, but should be 0 as is an excluded day...
var b = businessHours;
return (Convert.ToInt32(b) != 0);
modified 16-Apr-12 12:28pm.
|
|
|
|

|
Hi Barry
Try this:
public void BusinessHoursSample()
{
TimeRange timeRange = new TimeRange(
new DateTime( 2012, 4, 06, 10, 30, 00 ),
new DateTime( 2012, 4, 06, 18, 00, 00 ) );
double businessHours = CalculateBusinessHours( timeRange );
Console.WriteLine( "business hours: " + businessHours );
}
private double CalculateBusinessHours( ITimePeriod timePeriod )
{
double businessHours = 0;
CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
filter.AddWorkingWeekDays();
filter.CollectingHours.Add( new HourRange( 8, 18 ) );
filter.ExcludePeriods.Add( new Day( 2012, 4, 6 ) );
TimeRange collectorTimeRange = new TimeRange( timePeriod.Start.Date, timePeriod.End.Date.AddDays( 1 ) );
TimeCalendar calendar = new TimeCalendar( new TimeCalendarConfig { EndOffset = TimeSpan.Zero } );
CalendarPeriodCollector collector = new CalendarPeriodCollector( filter, collectorTimeRange, SeekDirection.Forward, calendar );
collector.CollectHours();
if ( collector.Periods.Count > 0 )
{
collector.Periods.Add( timePeriod ); TimePeriodIntersector<TimeRange> intersector = new TimePeriodIntersector<TimeRange>();
ITimePeriodCollection businessHourPeriods = intersector.IntersectPeriods( collector.Periods );
foreach ( TimeRange businessHourPeriod in businessHourPeriods )
{
businessHours += businessHourPeriod.Duration.TotalHours;
}
}
return businessHours;
}
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder
|
|
|
|
|

|
Thanks for this. Can't get it to work - see my posts under Jani. Would really appreciate any help you can both give. Thanks. Barry
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
Calculation of business hours (including holidays) using the Time Period Library for .NET
| Type | Tip/Trick |
| Licence | CPOL |
| First Posted | 13 Apr 2012 |
| Views | 8,378 |
| Bookmarked | 17 times |
|
|