I am trying to set my DateTime start variable to change based on what time it is now. my shifts(different start times) are 1: 6am-2pm 2: 2pm-10pm 3: 10pm-6am. I am having trouble writing the if statement to give the correct time.
The short version. I am trying to write C# if statement to figure out which of the the three start it is currently. Below is the code. above is the start times.
The logic I am trying to achieve is to have the DateTime start variable to be set to one of the 3 date time I have listed. Morning, Afternoon, or Evening. The start variable needs to be change values based on DateTime.Now. The View will be refreshing the page every 15 seconds. That will update the DateTime.Now variable.
Thank you for your time.
DateTime MORNING;
DateTime AFTERNOON;
DateTime EVENING;
if (DateTime.Now.Hour > 6 || (DateTime.Now.Hour == 6 && DateTime.Now.Minute >= 00))
MORNING = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 6, 00, 0);
else
MORNING = new DateTime(DateTime.Now.AddDays(-1).Year, DateTime.Now.AddDays(-1).Month, DateTime.Now.AddDays(-1).Day, 6, 30, 0);
if (DateTime.Now.Hour > 14 || (DateTime.Now.Hour == 14 && DateTime.Now.Minute >= 00))
AFTERNOON = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 14, 00, 0);
else
AFTERNOON = new DateTime(DateTime.Now.AddDays(-1).Year, DateTime.Now.AddDays(-1).Month, DateTime.Now.AddDays(-1).Day, 14, 00, 0);
if (DateTime.Now.Hour > 20 || (DateTime.Now.Hour == 20 && DateTime.Now.Minute >= 00))
EVENING = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 20, 00, 0);
else
EVENING = new DateTime(DateTime.Now.AddDays(-1).Year, DateTime.Now.AddDays(-1).Month, DateTime.Now.AddDays(-1).Day, 20, 00, 0);
DateTime start = ((EVENING > MORNING) ? EVENING : MORNING);
DateTime end = start.AddHours(8);
I'm not sure whether you need the MORNING, AFTERNOON, or EVENING variables elsewhere in your code, but they are not needed for this; I would remove them from my sample unless you need them in other locations. If you do need those variables, you can replace my start sets to new DateTime objects with the appropriate variable, but I wanted to demonstrate that the extra variables are not at all required for this. The following should work:
DateTime now = DateTime.Now;
DateTime MORNING = new DateTime(now.Year, now.Month, now.Day, 6, 0, 0);
DateTime AFTERNOON = MORNING.AddHours(8);
DateTime EVENING = AFTERNOON.AddHours(8);
DateTime start;
// Note that hour 22 is 10PM, not hour 20 as in your example
if (now.Hour >= 22 || now.Hour < 6)
{
// Evening
start = new DateTime(now.Year, now.Month, now.Day, 22, 0, 0);
AFTERNOON -= TimeSpan.FromDays(1);
MORNING -= TimeSpan.FromDays(1);
}
else if (now.Hour >= 14)
{
// Afternoon
start = new DateTime(now.Year, now.Month, now.Day, 14, 0, 0);
EVENING -= TimeSpan.FromDays(1);
MORNING -= TimeSpan.FromDays(1);
}
else
{
// Morning
start = new DateTime(now.Year, now.Month, now.Day, 6, 0, 0);
EVENING -= TimeSpan.FromDays(1);
AFTERNOON -= TimeSpan.FromDays(1);
}
DateTime end = start.AddHours(8);
Related
For example, I will be given a time on hours with type DateTime hours like this
for the starter
my starttime is 00:00
endtime is 02:00
and every time 30 minutes I like to input the value into a List<DateTime>
so, how can I get the value to put into a list that is look like this?
00:00
00:30
01:00
01:30
02:00
My Code
DateTime starTime = new DateTime();
DateTime endTimes = new DateTime();
DateTime interval = new DateTime();
List<DateTime> intervals = new List<DateTime>();
starTime = DateTime.ParseExact(fulldate + "00:00",
"yyyy/MM/dd HH:mm",
CultureInfo.InvariantCulture);
endTimes = DateTime.ParseExact(fulldate + "02:00",
"yyyy/MM/dd HH:mm",
CultureInfo.InvariantCulture); ;
interval = starTime;
for (int i = 0; i < 24; i++)
{
interval.AddHours(0.5);
intervals.Add(interval);
if (interval.ToString("HH:mm") == endTimes.ToString("HH:mm"))
{
break;
}
}
Can anyone help me to solve this?
With some assumption (that end time is on the same day, that your end time is always something that can be devided by 30 mins, ...) this would work.
var start = new TimeSpan(0, 0, 0);
var end = new TimeSpan(2, 0, 0);
var current = start;
List<DateTime> values = new List<DateTime>();
var startDate = DateTime.Now.Date; // editited after #pinkflowydx33's comment
values.Add(startDate + start);
while (current < end)
{
current = current.Add(new TimeSpan(0, 30, 0));
values.Add(startDate + current);
}
foreach (var v in values)
{
Console.WriteLine(v);
}
i prepared that type of solution. - It's loop over number, which represent - times of valueToChange - in this specific case between 30 minutes - and add to the startDate - 30 minutes and also saving to list.
using System;
public class Program
{
public static void Main()
{
List<DateTime> intervals = new List<DateTime>();
var changeValue = 30;
var startDate = new DateTime(2010, 05, 12, 13, 00, 00);
var endDate = new DateTime(2010, 05, 12, 14, 00, 00);
var timeIntervals = System.Math.Abs(startDate.Subtract(endDate).TotalMinutes / changeValue);
for (int i = 0; i < timeIntervals; i++)
{
startDate.AddMinutes(30);
intervals.Add(startDate)
}
}
}
In this case the start and end date are divided by 30 minutes without rest - so if there will be 13:00 and 13:12 - it's doesn't add the value to List - cause the value doesn't > 30.
For my app I need to know if Now() is between two values.
The user can set a start- and an end-time so he will not disturbed by a notification (during the night for example).
So if have got two TimePickers (start- and end-time) that the user can set.
Lets say the user sets 22:00 for the StartTime and 07:00 for the EndTime (this would cover the night).
How can I check if the DateTime.Now is between the selected Start and End time?
EDIT:
I only want this to work with the Hour and minutes part. So if the user sets the Start and End time this should work for every night.
First you need to convert everything to the same units (we'll use TimeSpan), then you need to see whether the start-end times cross midnight, and finally do your comparison based on the results of that check:
// convert everything to TimeSpan
TimeSpan start = new TimeSpan(22, 0, 0);
TimeSpan end = new TimeSpan(07, 0, 0);
TimeSpan now = DateTime.Now.TimeOfDay;
// see if start comes before end
if (start < end)
return start <= now && now <= end;
// start is after end, so do the inverse comparison
return !(end < now && now < start);
Here's a function to do it for you:
bool TimeBetween(DateTime datetime, TimeSpan start, TimeSpan end)
{
// convert datetime to a TimeSpan
TimeSpan now = datetime.TimeOfDay;
// see if start comes before end
if (start < end)
return start <= now && now <= end;
// start is after end, so do the inverse comparison
return !(end < now && now < start);
}
You would call it like:
bool silenceAlarm = TimeBetween(DateTime.Now, StartTime.Value, EndTime.Value);
Since you are only gathering two times without dates, you need to figure out if the two times are from the same day or not. If you put the StartTime, EndTime, and Now into TimeSpans:
if (StartTime > EndTime)
{
// the range crosses midnight, do the comparisons independently
return (StartTime < Now) || (Now < EndTime);
}
else
{
// the range is on the same day, both comparisons must be true
return StartTime < Now && Now < EndTime;
}
public static bool isCurrenctDateBetween(DateTime fromDate, DateTime toDate)
{
DateTime curent = DateTime.Now.Date;
if (fromDate.CompareTo(toDate) >= 1)
{
MessageBox.Show("From Date shouldn't be grater than To Date", "DateRange",MessageBoxButton.OKCancel, MessageBoxImage.Warning);
}
int cd_fd = curent.CompareTo(fromDate);
int cd_td = curent.CompareTo(toDate);
if (cd_fd == 0 || cd_td == 0)
{
return true;
}
if (cd_fd >= 1 && cd_td <= -1)
{
return true;
}
return false;
}
DateTime nowDate = DateTime.Now;
// set these to today + time from time picker
DateTime startDate = new DateTime(nowDate.Year, nowDate.Month, nowDate.Day,
selectedStart.Hour, selectedStart.Minute, 0);
DateTime endDate = new DateTime(nowDate.Year, nowDate.Month, nowDate.Day,
selectedEnd.Hour, selectedEnd.Minute, 0);
bool isBetween = nowDate < endDate && nowDate > startDate;
Update 08-Jun-2016
Not sure why the downvote was appropriate as this is a working solution. The OP did ask specifically for DateTime, however I do recommend using TimeSpan instead as per the answer by #Gabe.
Here's a working function as per my answer:
public static bool TimeBetween(DateTime check, DateTime start, DateTime end, bool inclusive = true)
{
var from = new DateTime(check.Year, check.Month, check.Day,
start.Hour, start.Minute, start.Second, start.Millisecond);
var to = new DateTime(check.Year, check.Month, check.Day,
end.Hour, end.Minute, end.Second, end.Millisecond);
if (inclusive)
return from <= check && to >= check;
return from < check && to > check;
}
Here's a working fiddle: https://dotnetfiddle.net/vZCXqv.
Full code:
using System;
public class Program
{
public static void Main()
{
var start = new DateTime(1, 1, 1, 9, 0, 0);
var end = new DateTime(1, 1, 1, 17, 0, 0);
Console.WriteLine("{0} - Too early", TimeBetween(new DateTime(2014, 1, 1, 08, 59, 59, 999), start, end));
Console.WriteLine("{0} - On start time exclusive", TimeBetween(new DateTime(2014, 1, 1, 09, 00, 00, 000), start, end, false));
Console.WriteLine("{0} - On start time inclusive", TimeBetween(new DateTime(2014, 1, 1, 09, 00, 00, 000), start, end));
Console.WriteLine("{0} - After start time", TimeBetween(new DateTime(2014, 1, 1, 09, 00, 00, 001), start, end));
Console.WriteLine("{0} - Before end time", TimeBetween(new DateTime(2014, 1, 1, 16, 59, 59, 999), start, end));
Console.WriteLine("{0} - On end time inclusive", TimeBetween(new DateTime(2014, 1, 1, 17, 00, 00, 000), start, end));
Console.WriteLine("{0} - On end time exclusive", TimeBetween(new DateTime(2014, 1, 1, 17, 00, 00, 000), start, end, false));
Console.WriteLine("{0} - Too late", TimeBetween(new DateTime(2014, 1, 1, 17, 00, 00, 001), start, end));
}
public static bool TimeBetween(DateTime check, DateTime start, DateTime end, bool inclusive = true)
{
var from = new DateTime(check.Year, check.Month, check.Day, start.Hour, start.Minute, start.Second, start.Millisecond);
var to = new DateTime(check.Year, check.Month, check.Day, end.Hour, end.Minute, end.Second, end.Millisecond);
if (inclusive)
return from <= check && to >= check;
return from < check && to > check;
}
}
Just do straight comparison.
if(date > startdate && date < enddate)
Dupe of Find if current time falls in a time range
DateTime start = new DateTime(2009, 12, 9, 10, 0, 0));
DateTime end = new DateTime(2009, 12, 10, 12, 0, 0));
DateTime now = DateTime.Now;
if ((now > start) && (now < end))
{
//match found
}
Timespan, again, taken from dupe.
TimeSpan start = new TimeSpan(10, 0, 0);
TimeSpan end = new TimeSpan(12, 0, 0);
TimeSpan now = DateTime.Now.TimeOfDay;
if ((now > start) && (now < end))
{
//match found
}
I use this, so you can pass DateTime directly:
public static bool TimeBetween(DateTime time, DateTime startDateTime, DateTime endDateTime)
{
// get TimeSpan
TimeSpan start = new TimeSpan(startDateTime.Hour, startDateTime.Minute, 0);
TimeSpan end = new TimeSpan(endDateTime.Hour, endDateTime.Minute, 0);
// convert datetime to a TimeSpan
TimeSpan now = time.TimeOfDay;
// see if start comes before end
if (start < end)
return start <= now && now <= end;
// start is after end, so do the inverse comparison
return !(end < now && now < start);
}
Let's say we have a Date range like: 2019-05-26 07:12:00 to 2019-11-26 19:15:00
And we got Two timespans: 07:00 and 08:00 for calculation of breakfast.
Now I had to calculate how many time this time overlap occurred.
this is what I wrote so far but I know I miss some times in start & end of periods:
var breakfast = 0;
for (DateTime date = StartDate; date.Date <= EndDate; date = date.AddDays(1))
{
if (date.TimeOfDay >= new TimeSpan(0, 07, 00, 00) && date.TimeOfDay <= new TimeSpan(0, 08, 00, 00))
{
breakfast++;
}
}
///////
var lunch = 0;
for (DateTime date = StartDate; date.Date <= EndDate; date = date.AddDays(1))
{
if (date.TimeOfDay >= new TimeSpan(0, 13, 00, 00) && date.TimeOfDay <= new TimeSpan(0, 14, 00, 00))
{
lunch++;
}
}
Any help will be appreciated.
Now, you say that you have a date range. StartDate and EndDate. Let's say they have values as follows:
StartDate = new DateTime(2019,05,26,07,12); // "2019-05-26 07:12"
EndDate = new DateTime(2019,11,26,19,15); // "2019-11-26 19:15"
Now when you write:
for (DateTime date = StartDate; date.Date <= EndDate; date = date.AddDays(1))
each time this loop runs, you will get date.TimeOfDay as 07:12 for each iteration. This means that if the time component of StartDate does not fall between 07:00 and 08:00 range, then it is not going to fall for any other day in the loop as well.
Therefore, we can simplify the whole counting process in the following way:
var breakfast = 0;
if (StartDate.TimeOfDay >= new TimeSpan(0, 07, 00, 00) && StartDate.TimeOfDay <= new TimeSpan(0, 08, 00, 00))
{
breakfast++;
breakfast += EndDate.Date.Subtract(StartDate.Date.AddDays(1)).Days;
if(EndDate.TimeOfDay >= new TimeSpan(0, 07, 00, 00))
breakfast++;
}
the condition is Time in and Time out (e.g 02/01/2015 02:55 'til 02/02/2015 05:55) that is more than a day. I already computed the total hours of Time in and Time out, and I want to know if the total hours has passed between 23:00(11:00PM ) up to 06:00AM and get the total of it
var hours = (datevalue1 - datevalue2).TotalHours;
or
Timespace ts= (datevalue1 - datevalue2);
var hours = ts.Value.TotalHours;
Try this way.. DateTime.Parse().Subtract()
eg:
string startTime = "11:00 PM";
string endTime = "6:00 AM";
TimeSpan duration = DateTime.Parse(endTime).Subtract(DateTime.Parse(startTime));
Console.WriteLine(duration);
Console.ReadKey();
OR
TimeSpan is the object you need:
TimeSpan span = (DateTime.Now - DateTime.Now);
String.Format("{0} days, {1} hours, {2} minutes, {3} seconds",
span.Days, span.Hours, span.Minutes, span.Seconds);
You can calculate it by passing over time. when its night time add it to TimeSpan.
DateTime timeIn = new DateTime(2015, 09, 29, 10, 11, 3); // 29-09-2015 at 10:11:03
DateTime timeOut = new DateTime(2015, 10, 1, 2, 19, 18); // 01-10-2015 at 02:19:38
TimeSpan nightTime = new TimeSpan(); //total amount of night time
TimeSpan passLength = new TimeSpan(0, 0, 0, 1); // length of time to pass at each iteration (1s)
while (timeIn < timeOut) // do it until timeIn reaches timeOut
{
timeIn = timeIn.Add(passLength); // add 1 second to timeIn
if (timeIn.Hour < 6 || timeIn.Hour == 23) // if we are in range of night time
{
nightTime = nightTime.Add(passLength); // add 1 second to night time
}
}
Console.WriteLine(nightTime);
You can do lot of optimizations. for long times its not good idea to add 1 sec each time. you can add 1 day to TimeIn at each iterate then add only 6 hours to night time. after you get close to Timeout decrease length time
Here is a better way. first get days fast. then get rest of the time.
DateTime timeIn = new DateTime(2015, 09, 29, 10, 11, 3); // 29-09-2015 at 10:11:03
DateTime timeOut = new DateTime(2015, 10, 1, 2, 19, 18); // 01-10-2015 at 02:19:38
// Get days
TimeSpan passLength = new TimeSpan(1, 0, 0, 0); // one day per iterate
while (timeIn + passLength < timeOut)
{
timeIn = timeIn.Add(passLength);
nightTime = nightTime.Add(new TimeSpan(0, 7, 0, 0)); // 7 hours of a day passed is considered night time
}
// Get rest of the time
passLength = new TimeSpan(0, 0, 0, 1); // one second per iterate
while (timeIn < timeOut) // do it until timeIn reaches timeOut
{
timeIn = timeIn.Add(passLength); // add 1 second to timeIn
if (timeIn.Hour < 6 || timeIn.Hour == 23) // if we are in range of night time
{
nightTime = nightTime.Add(passLength); // add 1 second to night time
}
}
Console.WriteLine(nightTime);
You shouldn't be worry about rest of the time calculation performance. since the rest of the time is now less than 1 day which is only 86400 seconds.
Less than 86400 iterates should be fine for today's processors speed. how ever you can still optimize it farther away but you don't get much more performance.
A little bit different and faster approach:
static void Main(string[] args)
{
TimeSpan result = new TimeSpan();
DateTime dt1 = new DateTime(2015, 09, 29, 10, 11, 03);
DateTime dt2 = new DateTime(2015, 10, 01, 02, 19, 38);
DateTime d1 = new DateTime(dt1.Year, dt1.Month, dt1.Day, 0, 0, 0); //Date only
DateTime d2 = new DateTime(dt2.Year, dt2.Month, dt2.Day, 0, 0, 0); //Date only
//Count night time in first day
result += DateTime.Compare(dt1, d1.AddHours(6)) > 0 ? new TimeSpan(6, 0, 0) : new TimeSpan(dt1.Hour, dt1.Minute, dt1.Second);
if (DateTime.Compare(dt1, d1.AddHours(23)) > 0) result += new TimeSpan(dt1.Hour - 23, dt1.Minute, dt1.Second);
//Count night time in last day
result += DateTime.Compare(dt2, d2.AddHours(6)) > 0 ? new TimeSpan(6, 0, 0) : new TimeSpan(dt2.Hour, dt2.Minute, dt2.Second);
if (DateTime.Compare(dt2, d2.AddHours(23)) > 0) result += new TimeSpan(dt1.Hour - 23, dt2.Minute, dt2.Second);
//Count night time in middle days
int daysBetween = (int)(d2 - d1).TotalDays - 1;
result += new TimeSpan(daysBetween * 7, 0, 0);
Console.WriteLine("Night time: " + result);
Console.ReadKey();
}
Compare EndTime with your Range(23:00-06:00)
that is in your Case, check wether EndTime 05:55 < 06:00 and EndTime 05:55 > 23:00
You can subtract the DateTime values to get the TimeSpan in between. Then you can get the TotalHours in that
var hours = timeOut.Subtract(timeIn).TotalHours;
For example
timeIn = 29-09-2015 10:11:03;
timeOut = 01-10-2015 02:19:38;
hours = 52.14303137125;
My code below.I want to do user select 10.06.2015 09:00 - 12.06.2015 13:00 after I will show 2 days 2 hours.
But I want to do Working days and Working Hours beetween 09:00 - 18:00 well users when you 10.06.2015 09:00 - 12.06.2015 13:00 I want to show only 2,5 days.
How can I do?
DateTime t1 = dateTimePicker1.Value.Date;
DateTime t2 = dateTimePicker2.Value.Date;
string s1 = textBox9.Text;
string s2 = textBox10.Text;
DateTime dt1 = t1.AddMinutes(DateTime.Parse(s1).TimeOfDay.TotalMinutes);
DateTime dt2 = t2.AddMinutes(DateTime.Parse(s2).TimeOfDay.TotalMinutes);
var fark = dt2 - dt1;
label1.Text =
String.Format("{0}{1}{2}",
fark.Days > 0 ? string.Format("{0} gün", fark.Days) : "",
fark.Hours > 0 ? string.Format("{0} saat ", fark.Hours) : "",
fark.Minutes > 0 ? string.Format("{0} dakika ", fark.Minutes) : "").Trim();
Well you can assume that any days in the range, except the first and last are full working days. So you need (AllDaysInRange -2) + HoursInfirstDay + HoursInLastDay.
TimeSpan ts = t2 - t1;
ts.Days = ts.Days - 2; //Allow for the 2 end days
int Day1Hours = t1.Hours - 9;//This removes any hours between 00.00 and 09.00
if (day1Hours > 9) //Then the user was working past 18.00
ts.Days = ts.Days+1
else
ts.Hours = ts.Hours + day1Hours;
int Day2Hours = t2.Hours - 9;//This removes any hours between 00.00 and 09.00
if (day2Hours > 9) //Then the user was working past 18.00
ts.Days = ts.Days+1
else
ts.Hours = ts.Hours + day2Hours;
If you can get this to work (I have written it from memory), then I'd wrap the code to convert the hours of the end days into a method rather than repeating it.
According to DateTime Picker In WinForm How To Pick Time? post, you can change your DateTimePicker, to function with times as well.
To limit the range which the users can select, you can modify your ValueChanged event or write your own validation for it.
Probably the simplest is:
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
if (dateTimePicker1.Value.Hour < 10) // the 10 is just a random number, you can change it to your own limit
dateTimePicker1.Value = this.dateTimePicker1.Value.AddHours(10 - dateTimePicker1.Value.Hour);
}
To calculate your 2,5 day according to the working hours, i would write a function to handle this responsibility like:
private int TimeInWorkingHours(DateTime start, DateTime end, int firstHour, int lastHour)
{
int days = Math.Min(end.Subtract(start).Days - 2, 0) ;
int hoursInADay = lastHour - firstHour;
int result = days * hoursInADay;
result += start.Hour - firstHour;
result += lastHour - end.Hour;
return result;
}
This way you call TimeInWorkingHours(...) function with your start date and end date, also providing your first and last working hours.
First you calculate the worked days, than add the border hours. This way you get your worked hours which you can then divide by the work hours to get your working days.
try this
private void GetProperOfficeHours(ref DateTime date)
{
int minHour = 9, maxHour = 17;
if (date.Hour < minHour) //if earlier than office hours - start from 9am
{
date = date + new TimeSpan(9, 0, 0);
}
else if (date.Hour > maxHour) //if later than office hours - go to next day 9am
{
date = date.AddDays(1) + new TimeSpan(9, 0, 0);
}
}
Then ...
//assuming firstDate & lastDate have date and time
int[] weekendDays = new int[2] { 0, 6 }; // Sunday and Saturday
GetProperOfficeHours(ref firstDate);
GetProperOfficeHours(ref lastDate);
while (weekendDays.Contains((int)firstDate.DayOfWeek))
{
//get next date
firstDate = firstDate.AddDays(1);
}
while (weekendDays.Contains((int)lastDate.DayOfWeek))
{
//get prev date
lastDate = lastDate.AddDays(-1);
}
double hourDiff = Math.Abs(firstDate.Hour - lastDate.Hour) / 8.0; //8 office hours
double dayDifference = 0;
while (firstDate.Date <= lastDate.Date) //Loop and skip weekends
{
if (!weekendDays.Contains((int)firstDate.DayOfWeek)) //can also check for holidays here
dayDifference++;
firstDate = firstDate.AddDays(1);
}
dayDifference = dayDifference + hourDiff;
May need some tweaking, hope you find it helpful.
Try this
bool IsWorkingDay(DateTime dt)
{
int year = dt.Year;
Dictionary<DateTime, object> holidays = new Dictionary<DateTime, object>();
holidays.Add(new DateTime(year, 1, 1), null);
holidays.Add(new DateTime(year, 1, 6), null);
holidays.Add(new DateTime(year, 4, 25), null);
holidays.Add(new DateTime(year, 5, 1), null);
holidays.Add(new DateTime(year, 6, 2), null);
holidays.Add(new DateTime(year, 8, 15), null);
holidays.Add(new DateTime(year, 11, 1), null);
holidays.Add(new DateTime(year, 12, 8), null);
holidays.Add(new DateTime(year, 12, 25), null);
holidays.Add(new DateTime(year, 12, 26), null);
DateTime easterMonday = EasterSunday(year).AddDays(1);
if (!holidays.ContainsKey(easterMonday))
holidays.Add(easterMonday, null);
if (!holidays.ContainsKey(dt.Date))
if (dt.DayOfWeek > DayOfWeek.Sunday && dt.DayOfWeek < DayOfWeek.Saturday)
return true;
return false;
}
string WorkingTime(DateTime dt1, DateTime dt2)
{
// Adjust begin datetime
if (IsWorkingDay(dt1))
{
if (dt1.TimeOfDay < TimeSpan.FromHours(9))
dt1 = new DateTime(dt1.Year, dt1.Month, dt1.Day, 9, 0, 0);
else if (dt1.TimeOfDay > TimeSpan.FromHours(13) && dt1.TimeOfDay < TimeSpan.FromHours(14))
dt1 = new DateTime(dt1.Year, dt1.Month, dt1.Day, 14, 0, 0);
else if (dt1.TimeOfDay > TimeSpan.FromHours(18))
dt1 = new DateTime(dt1.Year, dt1.Month, dt1.Day, 9, 0, 0).AddDays(1);
}
else
dt1 = new DateTime(dt1.Year, dt1.Month, dt1.Day, 9, 0, 0).AddDays(1);
// Adjust end datetime
if (IsWorkingDay(dt2))
{
if (dt2.TimeOfDay < TimeSpan.FromHours(9))
dt2 = new DateTime(dt2.Year, dt2.Month, dt2.Day, 18, 0, 0).AddDays(-1);
else if (dt2.TimeOfDay > TimeSpan.FromHours(18))
dt2 = new DateTime(dt2.Year, dt2.Month, dt2.Day, 18, 0, 0);
else if (dt2.TimeOfDay > TimeSpan.FromHours(13) && dt2.TimeOfDay < TimeSpan.FromHours(14))
dt2 = new DateTime(dt2.Year, dt2.Month, dt2.Day, 13, 0, 0);
}
else
dt2 = new DateTime(dt2.Year, dt2.Month, dt2.Day, 18, 0, 0).AddDays(-1);
double days = 0;
double hours = 0;
double minutes = 0;
if (dt2 > dt1)
{
// Move dt1 forward to reach dt2 day chacking for working days
while (dt1.DayOfYear < dt2.DayOfYear)
{
if (IsWorkingDay(dt1))
days++;
dt1 = dt1.AddDays(1);
}
// Now get the worked hours as if were on the same day in the same manner
TimeSpan sdwt = dt2 - dt1;
if (dt1.TimeOfDay < TimeSpan.FromHours(13) && dt2.TimeOfDay > TimeSpan.FromHours(14))
sdwt -= TimeSpan.FromHours(1);
if (sdwt == TimeSpan.FromHours(8))
days++;
else
{
hours = sdwt.Hours;
minutes = sdwt.Minutes;
}
}
// There is a pause in between so adjust if the interval include it
var totalminutes = (days * 8 * 60 + hours * 60 + minutes);
string res = String.Format("{0} days {1} hours {2} minutes",
days,
hours,
minutes);
string totRes = String.Format("{0} days {1} hours {2} minutes",
totalminutes / 8 / 60,
totalminutes / 8,
totalminutes);
return res + "\r\n" + totRes;
}