Optimization With Dates and Events - c#

This is a bit of a tricky problem to explain but I will try my best.
I have a calendar of events. In these there are non-working days. When any part of an event lands in on on a non-working day, its days are extended until it reaches a working day.
See here:
I have an orange 1 day event.
When it is dragged to the non-working day, it extends:
This works great and works fine. Here is the problem. I only show 2 weeks of the calendar at a time. Therefore, first, I fetch the visible events that start, end or fall in the range. Then, I fetch the nonworking days for the range and dynamically add the non-working days to its length.
Here is where the problem is:
Say there is an event that starts Jan 28th and ends Jan 29th. This means it will not get fetched. But because of Non-Working Days, it would end up on Feb 6th lets say. Well because I did not fetch it in my first step, I will not see it from feb 4 to 15. That is essentially my problem.
The naive solution would be to grab all events and all non-working days and then pre-calculate all end days dynamically, then filter the visible ones there. But that will get very expensive very fast.
But I cannot think of any other solution. It needs to be dynamic. Does anyone have any creative ideas on how I could solve this in a non O(N^2) manner. Just a general outline of a solution would be very helpful. I do not mind modifying the db if needed.
Currently a schedule has a start date and Hours. I dynamically calculate an event's length because different employees work different hours which is why I cannot have static end dates.

Related

Quartz-scheduler scheduling job every 2 weeks ignoring previous misfires

I'm trying to schedule a job on a given day (user defined) on an interval of every 2 weeks and ignoring and previous misfires using Quartz-Scheduler.
For example:
If I set the start date to 7th Oct(Sunday) and today's date is 26th Oct, it should trigger on 4th Nov(Sunday), 18th Nov(Sunday)...
The only way I found to do this is using the WithCalendarIntervalSchedule extension with StartAt. The issue with this approach is that, if the start date is before today then all the misfires will be triggered when the trigger is being scheduled.
Cron expression and CronScheduleBuilder does not seem to allow this.
I cannot ignore misfires as i do not want triggers that failed to start on time for whatever reason to be ignored.
And i cannot force the start date to be after today.
Let me know if I'm missing anything, I've been looking for a solution to this for a couple of days now.
Turns out Quartz scheduler does not support schedule for every 2 weeks very well.
The trick to make it work is to set the start date to be the next DateTime that it should be triggered using the StartAt extension then use WithCalendarIntervalSchedule with WithIntervalInWeeks.

GetLastInputTime shows impossible time?

To determine, if PC was not used for certain amount of time, I'm using Win32API.GetLastInputTime() method. I'm just subtracting its value from DateTime.Now, and compare it with some value, stored in settings.
It worked perfectly before, but recently GetLastInputTime started to show completely ridiculous results - it shows me future time. Today it shows me July 2nd of 2016.
So, does anyone has any idea, what's happening? How does GetLastInputTime get time, and how it is possible, that this time is future one?
Since GetLastInputTime returns ticks as UInt32 (DWORD)
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724408(v=vs.85).aspx
you can have an integer overflow:
The elapsed time is stored as a DWORD value. Therefore, the time will
wrap around to zero if the system is run continuously for 49.7 days.
To avoid this problem, use the GetTickCount64 function. Otherwise,
check for an overflow condition when comparing times.
And thus have future dates:
13 May 2016 + 49.7 days == 2 July 2016
I think you can not use DateTime.Now because it depends on the time zone.
As described here, you have to use Environment.TickCount to get the idle time.

NodaTime addition when DST happens

Let's say I have the date 2014-11-2T00:00:00-0600 then I want to add 1 day, and have 2014-11-3T00:00:00-0700 .
Now if I do :
crtDay.Plus(Duration.FromStandardDays(1));
crtDay is a ZonedDateTime object
I end up with : 2014-11-2T23:00:00-0700 .
How do I move to the next day? (I could add hours until I moved to the next day, but it feels like there has to be a better way.)
Thanks.
(I'll assume from the values you gave that you are working in the US Mountain time zone.)
A "standard day" is 24 hours. However, on the day you mentioned, there are 25 hours in the calendar day, because the hour from 01:00 to 02:00 is repeated for the daylight saving time fall-back transition. Thus, you end up on the same day if you only add 24 hours.
In Noda Time, the ZonedDateTime structure is meant to represent a specific moment in time, with respect to a time zone. Thus, you can only move by linear instantaneous time, using Duration.
To move by calendar time, you'll have to take it's LocalDateTime and add a Period to it. If desired, you can then create a new ZonedDateTime from the result.
ZonedDateTime nextDay = zdt.LocalDateTime.PlusDays(1).InZoneLeniently(zdt.Zone);
Here I use InZoneLeniently for convenience. However, you should understand the behavior of that particular resolver. A different resolver (or a custom one) might be more appropriate, depending on your needs.
Say for example that you were starting at 1:30 on that day instead. The lenient resolver will assume you wanted to choose the latter of the two occurrences. Essentially you would be adding 25 hours even though 24 hours would still yield the same clock time. Perhaps your users might expect you to land on the first occurrence.
Also consider the spring-forward transition, where if you started at 2:30 then you'd land on date/time that doesn't exist. The lenient resolver will advance to the next valid clock time for the time zone - which might be acceptable, but it would have a different clock time of 2:00. Your users might expect you'd advance by a whole hour instead of just the next valid clock time.
The built-in resolvers are being reconsidered for Noda Time v2. See issue 295, and this alternate implementation.

C# - calculate if a date is six months older

I am trying to calculate if the given specified date is at least six months old. I am doing this:
if(DateTime.Now.AddMonths(-6)>date)
{
//Do something
}
Is this correct?
Some people say that this approach is wrong and will not give accurate results. Is the above is correct?
"6 months" is not a precise amount of time. It depends on the length of the months. In particular, you may well get different results from your calculation compared with date.AddMonths(6) < DateTime.Now. (Consider adding 6 months from August 30th vs taking away 6 months from February 28th... You may be okay, but you need to think about this carefully.)
You need to consider a few things carefully:
You're currently using DateTime.Now instead of DateTime.Today; how do you want the current time of day to affect things?
Is the "kind" of date UTC, unspecified or local? It makes a difference - DateTime is confusing, unfortunately.
How do you want to handle situations like the ones in the first paragraph?
Ultimately, if people are telling you it will not give accurate results, you should ask them for specific examples - you need to get a wealth of input data and desired results, add automated tests for them, and get them to pass. Then if anyone claims your code isn't working correctly, you should be able to challenge them to create another test case which fails, and justify their decision.
If you are only concerned about the date and not the time, use DateTime.Now.Date instead. Apart from that, I do not see any problems with the code you already have.

How does .NET determine the week in a TimeZoneInfo.TransitionTime?

Greetings
I'm trying to do some DateTime math for various time zones and I wanted to take daylight savings into account. Lets say I have a TimeZoneInfo and i've determined the appropriate AdjustmentRule for a given DateTime. Lets also say the particular TimeZoneInfo i'm dealing with is specified as rule.DaylightTransitionStart.IsFixedDateRule == false, so I need to figure out if the given DateTime falls within the start/end TransitionTime.Week values.
This is where I'm getting confused, what is .NET considering as a "week"? My first thought was it probably used something like
DayOfWeek thisMarksWeekBoundaries = Thread.CurrentThread.CurrentUICulture.DateTimeFormat.FirstDayOfWeek;
and went through the calendar assigning days to week, incrementing week every time it crossed a boundary. But, if I do this for May 2010 there are 6 week boundary buckets, and the max valid value for TransitionTime.Week is 5 so this can't be right.
Whats the right way to slice up May 2010?
This article http://msdn.microsoft.com/en-us/library/system.timezoneinfo.transitiontime.isfixeddaterule.aspx shows how to extract the IsFixedDateRule == false, see DisplayTransitionInfo
I finally realized whats going on, I think the property name "Week" is what threw me off. There might be 6 weeks in May (depending on how you count them), but any particular DayOfWeek shows up at most 5 times. The Week property doesn't really refer to what week the DayOfWeek is showing up in, its the nth DayOfWeek for that month--with the magic value 5 meaning its last so either the max n is 4 or 5 for a given month.

Categories

Resources