C# date range within date range restricted by threshold x - c#

I've asked a similar question before but this is more in depth given that I figured out could of things since then. So believe me it's not repeated.
My user will use the system to make a reservation of room space and provide a start date and an end date by which his reservation should expire. Now there is a threshold of x number of seats in the room. Many bookings could be placed on the same date range as long as the rooms are available.
What am finding difficulty dealing with is the multiple reservation on the same date, and even worst when it comes to booking a date range within a booked range. That is having a booking from 10oct example until 20, then another booking starting from let's say 11th oct till 30 or 5th nov. how can I keep track of this reservation? It's been killing me for the past few weeks.
I am using SQL database to store reservation form data and c# language of choice to develop asp application. Thanks in advance for the help.

Your bookings consist of two parts a start day and a duration. The booking exists for a set number of days for what I can tell. One way to standardize would be to convert all booking to a list of Jullian days that they exits on. This conversion is available in the Noda Time library and then you can utilize linqs set functions to see if a booking is overlapping. I am sure there are corner cases but that is how I would approach the problem

Related

Generating DateTimeOffsets for a 'local' time range

I'm unsure how best to approach a date/time problem in C#. I have a dataset which lists the working hours for a set of people. Basically, 'person X works 09:00 to 17:30, Monday-Friday'. Basically two TimeSpan-s, which are assumed to be local times for any given date. From this, I need to be able to create two DateTimeOffset-s for any day of the year for a given locale.
For example, if I wanted to generate the UK-based DateTimeOffset for the following dates, I'd get the following results:
2015-01-01: From 2015-01-01T09:00:00+00:00, to 2015-01-01T17:30:00+00:00
2015-07-01: From 2015-01-07T09:00:00+01:00, to 2015-01-07T17:30:00+01:00
Obviously the difference is just the timezone - the first is GMT, the second is BST. A working day isn't normally affected by time zone changes. This is dependent on the date given.
I need to be able to do this for any specified country / region, including those whose timezones change (as demoed above).
If it matters, this will be .NET on Windows.
Thanks for any help.

Find possible combinations

I am trying to make a function that returns all possible combinations of a given set of data.
It's for a hotel yield management problem
There are 3 factors to consider:
5 rooms available
18 incoming booking requests
7 days of booking
If a room is booked for a given day, that room cannot be booked further until it is free the next day.
I believe this might be a simple math problem, however it is not my strongest side, so I ask you for help in order to find the way to create all the possible booking combinations
Best regards
Edit:
As requested, here are some additional details:
The goal is to find the highest possible revenue.
All of the 18 requests come on different days, different stay length and room rates, but there are only 5 rooms in this "hotel".
So what I want is to find out how many booking combinations can be done in 7 days with 5 rooms and 18 requests.
Then later I would go through every combination and tally the price to find the best one (exhaustive search)
Does that help?
In your case i would make a brute force attack , because u have a fairly limited combinations. it would be n^3 complexity

How do I accurately represent a Date Range in NodaTime?

Goals
I have a list of LocalDate items that represent sets of start dates and end dates.
I would like to be able to store date ranges, so that I can perform operations on them as a set of overlapping or distinct ranges, etc.
Questions
Does NodaTime provide some sort of DateRange construct that I've missed in the docs?
Am I thinking about this wrong? Is there a more natural / preferred way to accomplish this that NodaTime already allows for?
Am I setting myself up for trouble by attempting to think about a date range using a LocalDate for a start and an end date?
I'm completely new to NodaTime and assuming that this is a conceptual misunderstanding on my part.
Update: I noticed a similar question on the subject from 2009, but that seems to refer to another utilies class; I'm assuming that since then NodaTime may have evolved to accomodate this situation.
Noda Time provides an Interval type for a range of Instant values, but it doesn't provide range types for the other types. Part of the reason for this is the nuance of how ranges are used for different types.
If I give you a range of instants, it is always treated as a half open interval. The start value is included, but the end value is excluded. Humans do this naturally any time we provide a time value, such as when I say an event runs from 1:00 to 2:00, clearly I mean that the event is over at 2:00, so 2:00 is excluded.
But with whole calendar date ranges, typically the end dates are inclusive. To represent the entire month of January (as a range of LocalDate values), I would probably say Jan 1st through Jan 31st, and I am including the last day in its entirety.
We could probably add some additional range types to enforce these things, but we would need to think about how much value there is in having them in the API when you could probably just create them as needed. I'm not saying I'm for or against it either way, but that's probably something to be debated on the Noda Time user group.
To answer your specific questions:
No, there is no predefined range class for local dates.
The only other thing to consider is that calendar math is usually done via the Period class. For example, to determine how many days there are between two calendar dates:
LocalDate ld1 = new LocalDate(2012, 1, 1);
LocalDate ld2 = new LocalDate(2013, 12, 25);
Period period = Period.Between(ld1, ld2, PeriodUnits.Days);
long days = period.Days;
No, there's nothing wrong with creating a range class of local dates, there just might not be a whole lot of advantage. You may do just as well by having two properties, StartDate and EndDate, on your own classes. Just be careful about the inclusiveness of the end dates, vs the exclusiveness you'd see with an interval or time range.
And lastly, you said:
... so that I can perform operations on them as a set of overlapping or distinct ranges, etc.
You're probably looking for operations like intersection, union, calculating gaps, sorting, etc. These and more are defined by the Time Period Library, but Noda Time doesn't currently have anything like that. If one was to create it, it should probably be in a companion library ("NodaTime.Ranges", perhaps?). Likely it wouldn't be desired to pull it into the core, but you never know...
If you do end up using that Time Period Library, please make sure you recognize that it works with DateTime only, and is completely oblivious to DateTimeKind. So in order to be productive with it, you should probably make sure you are only working with UTC values, or "unspecified" calendar dates, and try not to ask it things like "how many hours are in a day" because it will get it wrong for days with daylight saving time transitions.

What is the best way to represent "Recurring Events" in database?

I am trying to develop a scheduler- and calendar-dependent event application in C#, for which a crucial requirement is to represent recurring events in the database.
What is the best way to represent recurring events in a database?
More Details:
While creating the event I am also sending invites to the certain users and the invitees should be allowed to login to the meeting only during the specified window(meeting duration) or may be decline the login when the invitee attempts to login say, 5 minutes before the scheduled start of the meeting.
The sysjobs, sysjobsschedule and sysschedules tables in SQL Server does a pretty good job of this. I wouldn't reinvent the wheel, I'd just copy their design.
Here are some of the important fields from sysschedules
freq_type
How frequently a job runs for this schedule.
1 = One time only
4 = Daily
8 = Weekly
16 = Monthly
32 = Monthly, relative to freq_interval
64 = Runs when the SQL Server Agent service starts
128 = Runs when the computer is idle
freq_interval
Days that the job is executed. Depends on the value of freq_type. The default value is 0, which indicates that freq_interval is unused.
Value of freq_type Effect on freq_interval
1 (once) freq_interval is unused (0)
4 (daily) Every freq_interval days
8 (weekly) freq_interval is one or more of the following: 1 = Sunday 2 = Monday 4 = Tuesday 8 = Wednesday 16 = Thursday 32 = Friday 64 = Saturday
16 (monthly) On the freq_interval day of the month
32 (monthly, relative) freq_interval is one of the following: 1 = Sunday 2 = Monday 3 = Tuesday 4 = Wednesday 5 = Thursday 6 = Friday 7 = Saturday 8 = Day 9 = Weekday 10 = Weekend day
64 (starts when SQL Server Agent service starts) freq_interval is unused (0)
128 (runs when computer is idle) freq_interval is unused (0)
freq_subday_type
Units for the freq_subday_interval. Can be one of the following values:
Value Description (unit)
1 At the specified time
2 Seconds
4 Minutes
8 Hours
freq_subday_interval
Number of freq_subday_type periods to occur between each execution of the job.
freq_relative_interval
When freq_interval occurs in each month, if freq_interval is 32 (monthly relative). Can be one of the following values:
0 = freq_relative_interval is unused
1 = First
2 = Second
4 = Third
8 = Fourth
16 = Last
freq_recurrence_factor
Number of weeks or months between the scheduled execution of a job. freq_recurrence_factor is used only if freq_type is 8, 16, or 32. If this column contains 0, freq_recurrence_factor is unused.
Well, to store the recurrence rule itself, you could use a cut down version of RFC 5545 (and I really suggest you cut it down heavily). Aside from anything else, that will make it easy to export into other applications should you wish to.
After you've made that decision, for the database side you need to work out whether you want to store each occurrence of the event, or just one record for the repeated event, expanding it as and when you need to. Obviously it's considerably easier to query the database when you've already got everything expanded - but it makes it trickier to maintain.
Unless you fancy writing some pretty complex SQL which may be hard to test (and you'll want a lot of unit tests for all kinds of corner cases) I would suggest that you make the database itself relatively "dumb" and write most of the business logic in a language like Java or C# - either of which may be embeddable within stored procedures depending on your database, of course.
Another thing you need to ask yourself is whether you need to cope with exceptions to events - one event in a series changing time/location etc.
I have some experience with calendaring (I've spent most of the last year working on the calendar bit of Google Sync via ActiveSync) and I should warn you that things get complicated really quickly. Anything you can deem "out of scope" is a blessing. In particular, do you need to work in multiple time zones?
Oh, and finally - be very, very careful when you're doing actual arithmetic with calendar operations. If you're going to use Java, please use Joda Time rather than the built-in Calendar/Date classes. They'll help you a lot.
The accepted answer here is too convoluted. For example, if an event occurs every 5 days, the 5 is stored in freq_interval, but if it occurs every 5 weeks, the 5 is stored in freq_recurrence. The biggest problem is that freq_interval means three different things depending on the value of freq_type (number of days between occurrences for daily recurrence, day of the month for monthly recurrence, or days of the week for weekly or monthly-relative). Also, the 1,2,4,8... type sequence is used when it is unnecessary and less than helpful. For example, freq_relative_interval can only be "one of" the possible values. This lines up with a drop-down box or radio button type input, not a checkbox type input where multiple choices can be selected. For coding, and for human readability, this sequence gets in the way and just using 1,2,3,4... is simpler, more efficient, more appropriate. Finally, most calendar applications don't need subday intervals (events occurring multiple times in a day - every so many seconds, minutes, or hours).
But, having said this, that answer did help me refine my thoughts on how I am doing this. After mix and matching it with other articles and going from what I see in the Outlook calendar interface and a few other sources, I come up with this:
recurs
0=no recurrence
1=daily
2=weekly
3=monthly
recurs_interval
this is how many of the periods between recurrences. If the event recurs every 5 days, this will have a 5 and recurs will have 1. If the event recurs every 2 weeks, this will have a 2 and recurs will have a 2.
recurs_day
If the user selected monthly type recurrence, on a given day of the month (ex: 10th or the 14th). This has that date. The value is 0 if the user did not select monthly or specific day of month recurrence. The value is 1 to 31 otherwise.
recurs_ordinal
if the user selected a monthly type recurrence, but an ordinal type of day (ex: first monday, second thursday, last friday). This will have that ordinal number. The value is 0 if the user did not select this type of recurrence.
1=first
2=second
3=third
4=fourth
5=last
recurs_weekdays
for weekly and monthly-ordinal recurrence this stores the weekdays where the recurrence happens.
1=Sunday
2=Monday
4=Tuesday
8=Wednesday
16=Thursday
32=Friday
64=Saturday
So, examples:
So, every 4 weeks on Saturday and Sunday would be
recurs = 2 ==> weekly recurrence
recurs_interval = 4 ==> every 4 weeks
recurs_weekdays = 65 ==> (Saturday=64 + Sunday=1)
recurs_day and recurs_ordinal = 0 ==> not used
Similarly, Every 6 months on the first Friday of the month would be
recurs = 3 ==> monthly recurrence
recurs_interval = 6 ==> every 6 months
recurs_ordinal = 1 ==> on the first occurrence
recurs_weekdays = 32 ==> of Friday
None of this business of having a field that means three entirely different things depending on the value of another field.
On the user interface side of things, I let the user specify a date, start time, end time. They can then specify if they want a type of recurrence other than none. If so, the app expands the relevant section of the web-page to give the user the options required for the stuff above, looking a lot like the Outlook options, except there is no "every weekday" under daily recurrence (that is redundant with weekly recurrence on every mon-fri), and there is no yearly recurrence. If there is recurrence then I also require the user to specify an end-date that is within one year of today (the users want it that way, and it simplifies my code) - I don't do unending recurrence or "end after ## occurrences."
I store these fields with the user selections in my event table, and expand that out in a schedule table which has all occurrences. This facilitates collision detection (I am actually doing a facility reservation application) and editing of individual occurrences or refactoring of future occurrences.
My users are all in CST, and I thank the good Lord for that. It is a helpful simplification for now, and if in the future the user base is going to expand beyond that, then I can figure out how to deal with it then, as a well separated task.
UPDATE
Since I first wrote this, I did add daily occurrence with "Every weekday". Our users had a bit of a hard time with thinking that you could use Weekly recurrence for events happening from Thursday one week to Tuesday the next week and only on weekdays. It was more intuitive for them to have this, even if there was already another way that they could do it.
I have been thinking about this too, although have not implemented it but these are my thoughts for a simple solution.
When setting up an event thats recurring, have the user specify the "end date" and create individual events for each one (based on the recurring options). Because its a recurring event, set a unique "recurring ID" for each of these. This ID will then be used to mark an event as recurring and if you change a future event, you can prompt the user to apply this to the rest of the future events by deleting and recreating the recurring events with a new "recurring ID" which will also differentiate this recurring event from the previously ones that have changed.
Hope this makes sense and would like any comments.
I would record recurring events as two separate things in the database. First of all, in an events table, record each and every occurence of the event. Secondly, have recurrences table in which you record the details that you ask for to set up the recurring event. Start date, periodicity, number of occurences, etc.
Then you might think of tying it all together by putting the PK of recurrences into each of the event records as an FK. But a better design would be to normalise the event table into two tables, one which is just the barebones of an event, and one which has the details, which could now be referring to multiple events. That way every event record, recurring or not, has an FK to the PK of the eventdetails table. Then in eventdetails, record the PK of recurrences somewhere along with agenda, invitees, etc. The recurrence record does not drive anything. For instance, if you want a list of all recurring events, you look through eventdetails for all events with a non-null FK to recurrences.
You'll need to be careful to synchronise all of these things, so that you insert or delete events when the recurrence data changes.
"Aside from anything else"
does this include "the very requirements" ?
"that will make it easy to export into other applications should you wish to."
Do the stated requirements include "it must be easy to export the calendars to other applications" ? My impression was that the problem consisted solely of building the FIRST application.
that said, my own response :
You need to limit yourself/your user on the types of "recurrency" your sytem will be able to support. And "All of the above" or "No Limitations" will not be a valid answer if you/your user want(s) to end up with a usable application.

c# code efficency

I have to caculate the number of business days between a given time period which is simple enough, however taking into account public holidays adds in a dimension of complexity.
My solution is not what I would call elegant nor efficient as it retrieves public holidays and puts them in a list, checks to see if a date in the list matches a date within the given time period to be checked by incrementing the date from the start date.
ALthough this works fine I'd rather have a more efficient algorithm has anyone got any tips or recommend a different data strucuture to hold the public holidays?
If you've got the public holidays stored in order, in a list, you can just do a binary search to find where in the list the start of your time period falls, and another to find where in the list the end of the time period falls. Then you just need to take the "normal" difference (removing weekends) and subtract the count of items between the results of the binary searches.
Be careful of time periods which start or end on a public holiday!
(List<T>.BinarySearch method should be fine for you assuming you're using DateTime or some other naturally comparable time structure. Note the return value is negative if the key you're searching for isn't actually in the list (which it won't be most of the time). See the remarks in the docs.)
If you calculate the number of business days between the two dates so
TimeSpan t1 = Date1 - Date2;
int totalDays = t1.TotalDays;
Then using your two dates, count the number of public holidays in your list which fall between and subtract from the total days.
I would think this would work, unless there are some public holidays in there which span multiple days and then you would have to adjust your selection logic. Can you paste what you have done so far to get a judge of where you are at and exactly what method you are using pls. :-)
Thanks,
Andrew
Here is how to calculate business days with the ultimate efficiency:
http://alecpojidaev.wordpress.com/2009/10/29/work-days-calculation-with-c/

Categories