How to find overlapping hours of a timerange and a date range? - c#

I have a time range 11:00 PM to 5:00 AM. (night hours range)
I have date range for eg.,
2014-04-01 00:00:00 to 2014-04-02 23:59:59
Now I need to calculate how many night hours are present in the given date range.
For the above example it should return 11 hours 59 minutes 59 seconds
Explanation:
2014-04-01 00:00 AM to 2014-04-01 5:00 AM = 5 hours
2014-04-01 11:00 PM to 2014-04-02 5:00 AM = 6 hours
2014-04-02 11:00 PM to 2014-04-02 11:59:59 PM = 0 hour 59 minutes 59 seconds
one second approximation is okay.

If these are strings, you need to parse them to DateTime with DateTime.ParseExact method and then get difference them with - operator. This gets you a TimeSpan. I see your strings have different formats. You need to parse them matched format one by one.
After that, you can use TimeSpan properties like;
string s = "2014-04-01 00:00 AM";
var date = DateTime.ParseExact(s,
"yyyy-MM-dd HH:mm tt",
CultureInfo.InvariantCulture);
string s1 = "2014-04-01 5:00 AM";
var date1 = DateTime.ParseExact(s1,
"yyyy-MM-dd H:mm tt",
CultureInfo.InvariantCulture);
TimeSpan ts = date1 - date;
Console.WriteLine(string.Format(#"{0} hours {1} minutes {2} seconds",
ts.Hours, ts.Minutes, ts.Seconds));
Output will be;
5 hours 0 minutes 0 seconds
If they are already DateTime, just use - operator and use .Hours, .Minutes and .Seconds properties of TimeSpan structure.
There is a project called Calculating Business Hours which is calculate business hours between two DateTime. You can implement your own night shift hours based this project.

You can use the CalendarPeriodCollector of the Time Period Library for .NET:
// ----------------------------------------------------------------------
public void NightHours()
{
CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
filter.CollectingHours.Add( new HourRange( 0, 5 ) ); // working hours
filter.CollectingHours.Add( new HourRange( 23, 24 ) ); // working hours
CalendarTimeRange testPeriod =
new CalendarTimeRange( new DateTime( 2014, 4, 1 ),
new DateTime( 2014, 4, 3 ) );
Console.WriteLine( "Calendar period collector of period: " + testPeriod );
CalendarPeriodCollector collector =
new CalendarPeriodCollector( filter, testPeriod );
collector.CollectHours();
Console.WriteLine( "Duration: " + new DateDiff( collector.Periods.TotalDuration ) );
} // NightHours

Related

How can I check whether there is conflict in time from string like 6:00 PM to 9:00 PM

I am building something like exam datesheet. I'm currently having issues in finding conflicts between time..
I have a List of strings that stores time intervals like-
List<string> times = new List<string>();
times.Add("6:00 PM to 9:00 PM");
times.Add("10:00 AM to 1:00 PM");
Now suppose, if want to add below time to the list, I first want to check it does not conflict with the time that is already there.
So, in below case, it should not be added.
if(NotConflict("5:00 PM to 7:00 PM"))
times.Add("5:00 PM to 7:00 PM");
But the following can be added since there is no conflict.
if(NotConflict("2:00 PM to 5:00 PM"))
times.Add("2:00 PM to 5:00 PM");
I cannot use DateTime here because it the very old system and time is being stored like above. And it being used at many places.
This should work:
private static Tuple<DateTime, DateTime> ParseDate(string dateTimes)
{
var split = dateTimes.Split(new[] { " to " }, StringSplitOptions.None);
var time1 = DateTime.ParseExact(split[0], "h:mm tt",
CultureInfo.InvariantCulture);
var time2 = DateTime.ParseExact(split[1], "h:mm tt",
CultureInfo.InvariantCulture);
return Tuple.Create(time1, time2);
}
private static bool NotConflict(IEnumerable<string> times, string time) {
var incTime = ParseDate(time);
return !times.Any(t => {
var parsed = ParseDate(t);
return incTime.Item1 <= parsed.Item2 && parsed.Item1 <= incTime.Item2;
});
}
public static void Main()
{
var times = new List<string>();
times.Add("6:00 PM to 9:00 PM");
times.Add("10:00 AM to 1:00 PM");
Console.WriteLine("No Conflict 5:00 PM to 7:00 PM: {0}", NotConflict(times, "5:00 PM to 7:00 PM"));
Console.WriteLine("No Conflict 2:00 PM to 5:00 PM: {0}", NotConflict(times, "2:00 PM to 5:00 PM"));
}
ParseDate will return a formatted tuple with the start and end time in Item1 and Item2 respectively. Then you simply use Linq's Any function to filter and make sure that you don't return any that fall within the bounds.
See the DotNet fiddle here.

Getting time between two times with time span of one hour

I have two times like
Time A:09:00 AM
and Time B:06:00 PM
I want to get the total hours between Time A and Time B
and show it with the time span of 1 hour
e.g:
09:00 AM
10:00 AM
11:00 AM
12:00 PM
upto
06:00 PM
I think you need something like;
DateTime dt1 = DateTime.Parse("09:00 AM");
DateTime dt2 = DateTime.Parse("06:00 PM");
while (dt1 <= dt2)
{
Console.WriteLine(dt1.ToString("hh:mm tt"));
dt1 = dt1.AddHours(1);
}
Output will be;
09:00 AM
10:00 AM
11:00 AM
12:00 PM
01:00 PM
02:00 PM
03:00 PM
04:00 PM
05:00 PM
06:00 PM
Here's a demonstration.
I'm sorry but I don't understand why you interested in TimeSpan on this case. It is a duration in time. You need to get every hour times with DateTime.
Use this function:
public static IEnumerable<DateTime> GetHours(DateTime startTime, DateTime endTime)
{
var currentTime = startTime;
while (currentTime <= endTime)
{
yield return currentTime;
currentTime = currentTime.AddHours(1);
}
}
If you just need the number of hours between two events, you can use a variation of
(endTime - startTime).TotalHours
This will return a double. To calculate the number of items returned from the iterator, use
(int)(endTime - startTime).TotalHours + 1

How to calculate hours between 2 different dates in c#

I have been building a program where i need to calculate the difference between different dates....... its a network outage program i want to calculate down time between different dates e.g network was down on 08/06/2013 9:00 AM and was restored on 09/06/2013 10:00 PM.... the down time should be 34 hours......... i have been able to calculate the days but i want this in hour format so anyone please help me.............
i m using datetimePicker to get the date and time at the same time.
i have been using the below mentioned code for that purpose
dateTimePicker1.Format = DateTimePickerFormat.Custom;
dateTimePicker1.CustomFormat = " dd/MM/yyyy hh:mm tt ";
dateTimePicker2.Format = DateTimePickerFormat.Custom;
dateTimePicker2.CustomFormat = " dd/MM/yyyy hh:mm tt ";
ts1 = dt2.Subtract(dt1);
richTextBox1.Text = "The Hours Difference is:\t" + dt2.Subtract(dt1).Hours + "\n The Minute Difference is:\t" + dt2.Subtract(dt1).Minutes;
You can use the .Net timespan class for this.
System.DateTime firstDate = new System.DateTime(2006, 9, 13, 12, 0, 0);
System.DateTime SecondDate = new System.DateTime(2006, 9, 13, 0, 0, 0);
System.TimeSpan diffResult = firstDate.Subtract(SecondDate);
diffResult will contain all the differences in firstDate and secondDate in year, month, day, hour, minutes and seconds.
You can get any datepart from this:
diffResult.Days
diffResult.Hours
diffResult.Minutes
etc.
You need
dt2.Subtract(dt1).TotalHours
and
dt2.Subtract(dt1).TotalMinutes

To get Calculate Time Worked

I currently build a system there is a part to manage Employee timein and timeout, i want to calculate this
***night shift (Must Work 8 Hr)***
startTime- 10.00 PM
endTime- 06.00 AM
So I want to calculate actually worked hours for that date (timein - timeout). What I have done is
TimeSpan duration = DateTime.Parse(endTime).Subtract(DateTime.Parse(startTime));
Output :16:00
What I want is 8:00
Eg 2
startTime- 10.00 PM
endTime- 05.00 AM
Out Put : 7:00
How can i done this?
You have to use date with time as well to exact hours between two times. As you would be having different dates in the time. Assume shift starts at 18 march, 2013 at 10:00PM and ends 19 march, 2013 5:00AM
Try to use Timespan like;
DateTime a = new DateTime(2008, 01, 02, 23, 30, 00);
DateTime b = new DateTime(2008, 01, 03, 06, 30, 00);
TimeSpan duration = b - a;
Console.WriteLine(duration);
Output will be
07:00:00
Here is a DEMO.
A TimeSpan object represents a time interval (duration of time or
elapsed time) that is measured as a positive or negative number of
days, hours, minutes, seconds, and fractions of a second.

Best class to represent a time

I'm working on timetabling application and I have a class:
called ClassOption representing a possible time to have a class.
with fields(/properties): Day, StartTime, EndTime, and Weeks.
Now Day is easy it's type is DayOfWeek
Weeks is going to require me to make a custom class because it is represented by the universities own in-semester weeks notation or in a calendar week, but basically will come down to a set of integers, eventually.
But what calls should I use for StartTime and EndTime.
They are a time, but without any Date information.
DateTime seems like a reasonable choice, but they could be on any date. (/many dates)
By business logic they are both on the hour, but that doesn't really matter
If you're happy to use a third party library which isn't quite at v1 yet, I'd like to plug Noda Time. You'd use the LocalTime struct.
If you're stuck with the base class library, you might want to use TimeSpan, or you could stick with DateTime. Obviously I think that LocalTime would be a more elegant solution though :)
Oh, and if you do use Noda Time, please let us know if you have any feature requests or comments...
You can use the DateDiff class of the Time Period Library for .NET to represent a time period:
// ----------------------------------------------------------------------
public void DateDiffSample()
{
DateTime date1 = new DateTime( 2009, 11, 8, 7, 13, 59 );
Console.WriteLine( "Date1: {0}", date1 );
// > Date1: 08.11.2009 07:13:59
DateTime date2 = new DateTime( 2011, 3, 20, 19, 55, 28 );
Console.WriteLine( "Date2: {0}", date2 );
// > Date2: 20.03.2011 19:55:28
DateDiff dateDiff = new DateDiff( date1, date2 );
// description
Console.WriteLine( "DateDiff.GetDescription(1): {0}", dateDiff.GetDescription( 1 ) );
// > DateDiff.GetDescription(1): 1 Year
Console.WriteLine( "DateDiff.GetDescription(2): {0}", dateDiff.GetDescription( 2 ) );
// > DateDiff.GetDescription(2): 1 Year 4 Months
Console.WriteLine( "DateDiff.GetDescription(3): {0}", dateDiff.GetDescription( 3 ) );
// > DateDiff.GetDescription(3): 1 Year 4 Months 12 Days
Console.WriteLine( "DateDiff.GetDescription(4): {0}", dateDiff.GetDescription( 4 ) );
// > DateDiff.GetDescription(4): 1 Year 4 Months 12 Days 12 Hours
Console.WriteLine( "DateDiff.GetDescription(5): {0}", dateDiff.GetDescription( 5 ) );
// > DateDiff.GetDescription(5): 1 Year 4 Months 12 Days 12 Hours 41 Mins
Console.WriteLine( "DateDiff.GetDescription(6): {0}", dateDiff.GetDescription( 6 ) );
// > DateDiff.GetDescription(6): 1 Year 4 Months 12 Days 12 Hours 41 Mins 29 Secs
} // DateDiffSample
I'd use either DateTime, which can be used with time values only while ignoring the date, or with a TimeSpan, which can represent the time elapsed since midnight, and thus a time of day. In fact, that's exactly how it's used in a DateTime object, when you ask for the TimeOfDay, you get a TimeSpan.
Both are good in that they give you a set of convenient arithmetic operations to compare, add and subtract times. Just ignore the Date portion.

Categories