I am a junior programmer, just starting out. I have been given a task determining whether events (that will be occurring over and over again every year) are currently happening. The events are stored in a database with in the format Month/Day start date to Month/Day end date, but no year. To make matters more complicated the events do not span the normally calendar year, they occur on a fiscal year between July 1 one year to June 30 the next year. It seems it is there is no way to have a DateTime object without a year, and I really don’t want to take the approach using an arbitrary year, because I don’t think this will work out in the long run. As I understand it this something new our project will be doing more and more, displaying information (or not displaying information) based on the month and day of the year. Given the current date, and an event that I know the start date and end date in month/day format, how can I tell if the event is currently happening? And remember this could span a change in calendar year. What would be really great if I could build this functionality into a linq query so that I don’t even bother pulling the events I don’t care about from the database, but I will take what I can get to make it work. The language we are using is C#. Thanks
Sorry about the structure of my post, I have not used stack overflow much The Data in the Database is structured somewhat like this:
StartDate | EndDate
-------------|----------
3/21 | 4/15
4/25 | 5/6
11/30 | 3/7
And yes it is stored as a varchar.
I would strongly recommend that you refactor your database to be more amenable to querying - you don't want to be having to parse the string values for every row, on every query. Additionally, you can add an extra field to indicate that the event is cross-year, i.e. that the "start" is after the "end", as per your final example. So you'd have something like:
StartDay StartMonth EndDay EndMonth CrossYear
21 3 15 4 False
25 4 6 5 False
30 11 7 3 True
At that point you can write a query reasonably easily. For example:
DateTime date = ...; // Wherever you get this from
var activeEvents = db.Events.Where
(e =>
// Regular case
(e.CrossYear == false &&
(date.Month > e.StartMonth || (date.Month == e.StartMonth && date.Day >= e.StartDay)) &&
(date.Month < e.EndMonth || (date.Month == e.EndMonth && date.Day <= e.EndDay))) ||
// Cross-year case, basically, just invert start and end... conditions
(e.CrossYear == true &&
(date.Month < e.StartMonth || (date.Month == e.StartMonth && date.Day <= e.StartDay)) &&
(date.Month > e.EndMonth || (date.Month == e.EndMonth && date.Day >= e.EndDay))));
You could express the same result more simply by using multiplication to turn month/day into a single number, e.g.
int pseudoDayOfYear = date.Month * 100 + date.Day;
var activeEvents = db.Events.Where
(e =>
// Regular case
(e.CrossYear == false &&
pseudoDayOfYear >= e.StartMonth * 100 + e.StartDay &&
pseudoDayOfYear <= e.EndMonth * 100 + e.EndDay) ||
// Cross-year case
(e.CrossYear == true &&
pseudoDayOfYear <= e.StartMonth * 100 + e.StartDay &&
pseudoDayOfYear >= e.EndMonth * 100 + e.EndDay));
This works because there are never any months with over 100 days in, but it's a bit ugly IMO.
See more on this question at Stackoverflow