In my project I can block internet access completely in specific times but in a current date.
I did this by using a timer. This timer checks the start time and end time and also controls in every 5 seconds to disable and enable internet connection by using the start time and end time given by user. Now I want to do the same thing in different days not only for the current date. I want to check every day in every 5 seconds of a day by timer if a disable/enable time interval is given by the user for that specific date.
if (currentDate == chosenDate)
{
if ((currenttime >= starttime) && (currenttime <= endtime))
{
timerForHour.Enabled = true;
if (isConnectedToNetwork)
{
findNetworkName();
Disable(networkName);
}
}
else
{
exitFlag = true;
Enable(networkName);
}
}
else if(currentDate!=chosenDate)
{
}
This is my code what am I going to do in this else if section?. Thanks.
I think you are going about this the wrong way. Don't think about it in terms of "if it's today or not", instead think about it in a more general way: "does the day match or not, if it does then are we within the time range acceptable?". Without knowing more about how you are storing the day / time ranges you are using I can offer the following using LINQ:
IsInternetAllowed = false;
DateTime dateOfInterest = datesToRestrict
.FirstOrDefault(dt => dt.Date == DateTime.Now.Date);
if (dateOfInterest != null)
{
if (timesToAllowDict.ContainsKey(DateTime.Now.Date))
{
List<Tuple<DateTime, DateTime>> lstAllowed =
timesToAllowDict[DateTime.Now.Date];
IsInternetAllowed = lstAllowed
.FirstOrDefault(time =>
DateTime.Now.Time > time.Value1 &&
DateTime.Now.Time < time.Value2) != null;
}
}
if (IsInternetAllowed)
Enable(networkName);
else
Disable(networkName);
I make the following assumptions about your data:
There are potentially multiple times allowed per day.
Any time that network access is not allowed it is disabled.
You store your allowed dates & times in a
Dictionary<DateTime, List<Tuple<DateTime, DateTime>>> structure.
That structure represents Date, List of times allowed (start then end).
Each day is added separately (one dictionary key per day allowed).
It is likely that with some streamlining you could remove the need to have a dictionary structure and only use the start & end times instead.
Related
I have Events page, In that displaying past present and future events counts and list. Here I'm facing a issue form QA team.
Example:
**Event date** is : 2022-01-20 08:00:00.000
**Current datetime** is: 2022-01-20 10:00:00.000
now based on above dates , we need to display event as past event because of two hours less than the Current datetime
if (planEvents.Count > 0)
{
switch (statusID)
{
case (int)GenericEnum.EventStatus.TodaysEvents:
events = planEvents.Where(o => o.EventDate.Date == DateTime.Today.Date).Skip(startIndex - 1).Take(pageSize).ToList();
totalCount = planEvents.Where(o => o.EventDate.Date == DateTime.Today.Date).ToList().Count();
break;
}
}
I tried above code but it's only returning date matching records but not hours comparison. can any once please help me.
First off, you should probably use UTC for all times, but that's a different issue. I don't really understand the use case you're after, but you can use the current time and add or subtract time units to create a range start and end. Not tested, but you should have something like this to select from a date range:
var start = DateTime.Now.AddHours(-2); // start from 2 hours ago
var end = DateTime.Now.AddHours(2); // end 2 hours from now
events = planEvents.Where(x => x.EventDate > start && x.EventDate < end);
Considering present events are the one falls within the current hour. Not tested, but it should work
if (planEvents.Any()) //Use Any method to improve performance
{
switch (statusID)
{
case (int)GenericEnum.EventStatus.TodaysEvents:
var todaysEvents = planEvents.Where(o => o.EventDate.Date == DateTime.Today.Date);
var todaysTotalEvents = todaysEvents.Count();
var currentHour = DateTime.Now.Hour;
var pastEvents = todaysEvents.Where(e=> e.EventDate.Hour < currentHour);
var presentEvents = todaysEvents.Where(e=> e.EventDate.Hour == currentHour);
var futureEvents = todaysEvents.Where(e=> e.EventDate.Hour > currentHour);
break;
}
}
I have a problem finding the last time in the day (the time it's the biggest) picture below, how can I get that time?
I have to compare this time with his shift, but when I do it, I always read for the first time.
This is my code:
foreach (var shift in shifts)
{
if (von.ZPZ_Von <= shift.Arbeitsbeginn.AddMinutes(-20) &&
bis.ZPZ_Bis >= shift.Arbetsende.AddMinutes(-10))
return null;
else if (von.ZPZ_Von >= shift.Arbeitsbeginn.AddMinutes(20) &&
bis.ZPZ_Bis >= shift.Arbetsende.AddMinutes(10))
return null;
else if (von.ZPZ_Von <= shift.Arbeitsbeginn.AddMinutes(5)
&& bis.ZPZ_Bis <= shift.Arbetsende.AddMinutes(10)
)
return shift;
}
It is a method that finds the shift of workers, and if in the correct shift the worker returns the shift, if the worker comes 20 minutes or works more than 10 minutes then returns null.
This looks like data for one day:
So I need to compare the ZPZ_Bis with the last, or rather, the time.
At the moment, my method always compares ZPZ_Bis with the first departure time, i. 1899-12-30 09:52:00.000 in this case.
I would be grateful if somebody could help me with this problem, I have not really known how to handle this in the last few days.
this is my whole method:
private A_Arbeitszeitplan DetectShift(List<A_Arbeitszeitplan> shifts, PRAESENZZEIT von, PRAESENZZEIT bis, List<PRAESENZZEIT>arrivals)
If you only wish to use the TimeSpan of your DateTime you can get it like so:
From a DateTime, you can use .TimeOfDay - but that gives you a
TimeSpan representing the time into the day (10 hours).
Of course you need to compare TimeSpans with eachother:
if (von.ZPZ_Von.TimeOfDay <= shift.Arbeitsbeginn.AddMinutes(-20).TimeOfDay &&
bis.ZPZ_Bis.TimeOfDay >= shift.Arbetsende.AddMinutes(-10).TimeOfDay)
return null;
I've been cracking my head over this algorithm for the past week and a half and i cant get it to work.
Basically i have an schedule (i know the Time value of the "borders")
and i have the red section (peoples movements in and out of the workplace). What i want is to know the time people spend at the workplace WITHIN their schedule, i dont care if they are there before or after work, or in the lunch break.
do you have any suggestions? on a mathematical theory or rule that i can apply here? or a similar problem you have seen you can point me to? i've been having a really hard time finding a solution. Any help would be appreciated.
For example:
Schedule:
7:30am (start) 12:00pm(lunchbreak)
1:30pm(endLunchBreak) 5:00pm(endOfWorkday)
People movements trough the day:
IN: 6:50am, OUT: 6:55am
IN: 7:00am, OUT: 11:45am
IN: 1:45pm, OUT: 5:05pm
So, my expected output would be a timespan of: 7:30 (it ignores time IN workplace outside of work schedule)
I would treat this as a state machine problem. There are four states: S+W+, S-W+, S+W-, S-W-.
Scheduled time corresponds to S+ states, worker present to W+ states. The objective is to add time in S+W+ to the intersection time.
The valid transitions are:
S+W+ End of schedule -> S-W+
S+W+ Worker leaves -> S+W-
S-W+ Start of schedule -> S+W+
S-W+ Worker leaves -> S-W-
S+W- End of schedule -> S-W-
S+W- Worker arrives -> S+W+
S-W- Start of schedule -> S+W-
S-W+ Worker arrives -> S-W+
Process events in time order, starting in state S-W-. If two events happen at the same time, process in either order.
On transition into S+W+, note the time. On transition out of S+W+, subtract the last noted time from the time of the transition, and add the result to the intersection time.
Break the day into 1440 one minute increments. This is your set space.
Set "S", the scheduled minutes, is a subset of that space.
Set "W", the amount of time spent on the job, is a subset of that space.
The intersection of "S" and "W" is the amount of time the person was there within their schedule (in minutes - convert to hh:mm per your needs).
Using other set algorithms you can find when they should have been there but weren't, etc.
You might want to look into using this library, but be careful, it completely ignores DateTime.Kind, is not time zone aware, and doesn't respect daylight saving time.
It is safe to use on Utc kinds.
Never use it on Local kinds.
If you use it on Unspecified kinds, make sure you understand what the context is. If it could possibly be a local time in some time zone that has DST, then your results may or may not be correct.
Other than that, you should be able to use its intersection function.
It sounds like LINQ should work well here. I've whipped up a short example, using my Noda Time library as it has better support for "time of day" than .NET, but you could adapt it if necessary.
The idea is basically that you have two collections of periods, and you're only interested in the intersection - you can find the intersection of any schedule period against any movement period - it's easy to discount periods that don't intersect by just using a 0-length period.
Here's the complete code, which does indeed give a total time of 7 hours and 30 minutes:
using System;
using System.Collections.Generic;
using System.Linq;
using NodaTime;
class Test
{
static void Main()
{
var schedule = new List<TimePeriod>
{
new TimePeriod(new LocalTime(7, 30), new LocalTime(12, 0)),
new TimePeriod(new LocalTime(13, 30), new LocalTime(17, 0)),
};
var movements = new List<TimePeriod>
{
new TimePeriod(new LocalTime(6, 50), new LocalTime(6, 55)),
new TimePeriod(new LocalTime(7, 0), new LocalTime(11, 45)),
new TimePeriod(new LocalTime(13, 45), new LocalTime(17, 05))
};
var durations = from s in schedule
from m in movements
select s.Intersect(m).Duration;
var total = durations.Aggregate((current, next) => current + next);
Console.WriteLine(total);
}
}
class TimePeriod
{
private readonly LocalTime start;
private readonly LocalTime end;
public TimePeriod(LocalTime start, LocalTime end)
{
if (start > end)
{
throw new ArgumentOutOfRangeException("end");
}
this.start = start;
this.end = end;
}
public LocalTime Start { get { return start; } }
public LocalTime End { get { return end; } }
public Duration Duration { get { return Period.Between(start, end)
.ToDuration(); } }
public TimePeriod Intersect(TimePeriod other)
{
// Take the max of the start-times and the min of the end-times
LocalTime newStart = start > other.start ? start : other.start;
LocalTime newEnd = end < other.end ? end : other.end;
// When the two don't actually intersect, just return an empty period.
// Otherwise, return the appropriate one.
if (newEnd < newStart)
{
newEnd = newStart;
}
return new TimePeriod(newStart, newEnd);
}
}
Public void Fee()
{
TimeSpan span1 = TimeSpan.FromHours(dtmIn.Value.Hour);
TimeSpan span2 = TimeSpan.FromHours(dtmOut.Value.Hour);
TimeSpan span3 = TimeSpan.FromMinutes(dtmIn.Value.Minute);
TimeSpan span4 = TimeSpan.FromMinutes(dtmOut.Value.Minute);
TimeSpan span5 = span2.Subtract(span1) + span4.Subtract(span3);
lblTotal.Text = (span5.TotalHours * 3).ToString("$#.00");
}
I do not want the user to be able to be able to clock in during PM and clock out during AM(basically overnight working). Also, not allowing the clock out time being before the clock in time.
You should call new TimeSpan(hours, minutes, seconds: 0) and check whether the in TimeSpan is > the out TimeSpan.
It appears from your code sample that dtmIn and dtmOut are nullable DateTime variables. If so, all you have to do is this:
if (dtmIn.Value >= dtmOut.Value)
{
//'in' time is equal to or greater than 'out' time
... show my error message ...
}
Of course you will need to ensure the DateTime? variables have a value (i.e. do appropriate error checking before using them in the expression).
You probably need to be a little more specific with your logic. Do you mean...
The user should be able to work overnight? If so, that means you need to check to make sure that the date they clocked in is the same as the date they clocked out. `
For example...
if (dtmIn.Value.Date != dtmOut.Value.Date)
{
...
}
The user should not be able to work more than 24 hours? If so, you should subtract the two dates and use the resulting TimeSpan to see how many days they worked.
For example...
if ((dtmOut.Value - dtmIn.Value).TotalDays > 1)
{
...
}
In neither case should you check the time explicitly. For one, if I worked 25 hours then my check out time would still be after the check in time.
The problem:
I am in process of implementing a scheduler for my advisor in school. The scheduler supposes to setup a 15 minutes interval time slot from 8:00 AM to 5:00 PM, Monday to Friday. In addition, the advisor will have to specify the start and end dates of the scheduler. The scheduler will also feature an option to specify if the 15 minutes time slot is not open. Meaning my advisor will be able to mark specific time slot as NOT AVAILABLE.
What I have so far:
I have created a simple class:
public class TimeSlot
{
public DateTime dateTime
{
get;
set;
}
public bool isAvailable
{
get;
set;
}
TimeSlot(DateTime dt, bool Avalible)
{
dateTime = dt;
isAvailable = Avalible;
}
}
The class basically represents an object for one time slot in the scheduler. I also have a list of time slots that keeps a list of the valid time slots:
List<TimeSlot> TSList = new List<TimeSlot>();
Note that a valid time slot means the following:
Date is within: Monday to Friday.
Time is within: 8:00 AM to 5:00 PM
Time slots are within: 15 minutes interval.
In addition, I have a method that fill in the TSList as the following:
private void button_Next_Click(object sender, RoutedEventArgs e)
{
/* Getting the values of fromDate and toDate from the GUI controls*/
DateTime fromDate = datePicker1.SelectedDate.Value;
DateTime toDate = datePicker2.SelectedDate.Value;
while (fromDate <= toDate)
{
/*This ensures that we only deal with days Monday to Friday*/
if (fromDate.DayOfWeek.ToString() != "Saturday" && fromDate.DayOfWeek.ToString() != "Sunday")
{
/*PROBLEM HERE!!*/
}
/*Updating fromDate: Incrementing fromDate by 1 day*/
fromDate = fromDate.AddDays(1);
}
}
Notes that I was only able to satisfy the first condition in my valid time slot conditions. Thus, I was only able to restrict the dates to be within Monday to Friday range.
The questions:
I am trying to achieve the missing two valid conditions for a time slot:
How to restrict the times to be only 8:00am to 5:00 pm?
How to make time slots separated by 15 minutes interval?
First, please use DayOfWeek.Saturday and DayOfWeek.Sunday for the comparision, converting to a string is not necessary...
Then just use a simple loop like
DateTime startSlot = fromDate.Date.AddHours(8); // Starts at 8:00AM
while (startSlot.Hour < 17) {
// Construct time slot class
startSlot = startSlot.AddMinutes(15);
}
This gives you startSlot values starting at 8:00am at every date ranging to 5pm (i.e. the last one is 4:45pm).
Why are you considering building this out of nothing?
Why are you not starting with one of the many calendar management programs that are available off the shelf? For example, Microsoft Outlook contains calendar and schedule management, and you can do all of what you describe, easily. It also integrates with other scheduling tools via .ICS files, it syncs with mobile devices, syncs with Google Calendar, and so on.
But there are lots of other options. Google Calendar is another obvious one.
I don't know why you would ever consider starting from scratch. Unless it's an academic exercise (and no, I don't mean that you work in academia), then you should use larger building blocks to start.
It's like building a structure, starting with sand and water, instead of pre-fabricated concrete block.
Just quick implementation. Let me know if you need some comments.
// Round interval
const int roundInterval = 15;
var remainder = fromDate.TimeOfDay.Minutes % roundInterval;
var curTime = remainder == 0 ? fromDate : fromDate.AddMinutes(roundInterval - remainder);
curTime = curTime.AddSeconds(-curTime.TimeOfDay.Seconds);
var delta = TimeSpan.FromMinutes(roundInterval);
while (curTime < toDate)
{
while (curTime.DayOfWeek == DayOfWeek.Saturday || curTime.DayOfWeek == DayOfWeek.Sunday)
{
curTime = curTime.Date.AddDays(1);
}
if (curTime.TimeOfDay.Hours < 8)
{
curTime = curTime.AddHours(8 - curTime.TimeOfDay.Hours);
curTime = curTime.AddMinutes(-curTime.TimeOfDay.Minutes);
continue;
}
if (curTime.TimeOfDay.Hours >= 17)
{
curTime = curTime.AddHours(24 - curTime.TimeOfDay.Hours);
curTime = curTime.AddMinutes(-curTime.TimeOfDay.Minutes);
continue;
}
TSList.Add(new TimeSlot(curTime, true));
curTime = curTime.Add(delta);
}
}
DateTime myScheduledTimeSlot = new DateTime(2010, 10, 26, 8, 45, 0);
// Use existing check to check day of week constraint...
// Check if the datetime falls on a correct minute boundary
switch (myScheduledTimeSlot.Minute)
{
case 0:
case 15:
case 30:
case 45:
// The time slot is valid
break;
default:
// The time slot is not valid
break;
}
It is pretty simple to check whether it falls in a 15 minute slot as you don't have weird boundaries keeping every hour identical. I'd recommend checking out Quart.NET if you want to save some time doing eventing/scheduling.