|
|
Hello,
I don't understand calculation method.
See the following code based on your sample.
Why the second period is only 8 hours an not 10 hours As I expected? It seems that last afternoon was not counted at all, while I think it should count for 2 hours.
Where am I wrong?
Thank You
public void CalculateBusinessHourSample()
{
CalendarTimeRange testPeriod1 = new CalendarTimeRange(new DateTime(2017, 6, 2, 14, 0,0 ), new DateTime(2017, 6, 5, 20, 0, 0));
Console.WriteLine("period: {0}", testPeriod1);
Console.WriteLine("business hours 1: {0}", CalculateBusinessHours(testPeriod1, null));
CalendarTimeRange testPeriod2 = new CalendarTimeRange(new DateTime(2017, 6, 2, 14, 0, 0), new DateTime(2017, 6, 5, 16, 0, 0));
Console.WriteLine("period: {0}", testPeriod2);
Console.WriteLine("business hours 2: {0}", CalculateBusinessHours(testPeriod2, null));
}
public double CalculateBusinessHours(CalendarTimeRange testPeriod, ITimePeriodCollection holidays = null)
{
CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
filter.AddWorkingWeekDays();
filter.CollectingHours.Add(new HourRange(8, 12));
filter.CollectingHours.Add(new HourRange(14, 18));
if (holidays != null)
{
filter.ExcludePeriods.AddAll(holidays);
}
CalendarPeriodCollector collector = new CalendarPeriodCollector(
filter, testPeriod);
collector.CollectHours();
double businessHours = 0.0;
foreach (ICalendarTimeRange period in collector.Periods)
{
businessHours += Math.Round(period.Duration.TotalHours, 2);
}
return businessHours;
}
modified 4-Jun-17 16:02pm.
|
|
|
|
|
|
Thank a lot
My business hours are
opening hours morning: from 8:30 To 12:00
opening hours afternoon: from 13:30 To 17:30
On days of week: Monday, Tuesday, Wednesday ,Thursday , Friday, Saturday (only from 8:30 To 12:00 )
My code is filter but i get wrong. please help me!
CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
filter.WeekDays.Add(DayOfWeek.Monday);
filter.WeekDays.Add(DayOfWeek.Tuesday);
filter.WeekDays.Add(DayOfWeek.Wednesday);
filter.WeekDays.Add(DayOfWeek.Thursday);
filter.WeekDays.Add(DayOfWeek.Friday);
filter.CollectingHours.Add(new HourRange(new Time(8,30),new Time(12,0)));
filter.CollectingHours.Add(new HourRange(new Time(13,30), new Time(17,30)));
filter.CollectingDayHours.Add(new DayHourRange(DayOfWeek.Saturday, new Time(8, 30), new Time(12, 0)));
|
|
|
|
|
Hi
You should not mix CollectingHours and CollectingDayHours using the CalendarPeriodCollectorFilter .
Use only CollectingDayHours by specifying any working day.
Please note that your CalendarPeriodCollectorFilter is missing the working day Saturday in WeekDays .
Cheers,
Jani Giannoudis
|
|
|
|
|
great! i worked
|
|
|
|
|
Hi,
My business hours are 20.00 - 07.00. For some reason both statements, new HourRange(20,7) and new HourRange(7,20), create an hourrange that starts at 07 and ends at 19:59:59.
¿Is there a way to use this for nocturnal business hours?
Thanks
|
|
|
|
|
Hi,
My business hours are 9 - 5:30, I noticed HourRange does not handle minutes, is it possible to account for the half hour?
|
|
|
|
|
You can use the Time class to specify fractions of a hour:
filter.CollectingHours.Add( new HourRange( new Time( 9 ), new Time( 17, 30 ) ) );
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder
|
|
|
|
|
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));
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();
filter.CollectingHours.Add(new HourRange(8, 18));
.........
pre>
---------------------------------------------------------------------
<big>diff = 30.0 when it should be in fact 40-2.5 = 37.5 business hours.</big>
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
|
|
|
|
|
Thanks, that really helps. I'll have to spend more time understanding the documentation as I can see that all the tools needed are there. I think I was also approaching the problem wrong, so wondered it there is a solution... What I should be doing is saying, our working day is 8-18, and then our investigators have 40 business hours to complete the task and submit the report. Is there a way to directly get the finishing time (taking into account holidays and weekends) if, for example, the call comes in at 06:00 in the mornings I.e. 2 hours before our business day starts. I'm not being lazy, just find the tools a little tricky to get to grips with.
Many thanks for your help already, it is much appreciated.
Barry
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.
|
|
|
|
|
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
|
|
|
|
|
You really are a star! Thanks again!
|
|
|
|
|
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
|
|
|
|
|