TEInRange class
The Is TE provides funcationality to test for occurrences after a deadline of the various DateTime components such as Year, Month, etc.
class TEInRange extends TExpression { DateTime _first; // The first DateTime that matches this TE DateTime _last; // The last DateTime that matches this TE (inclusive) TEIsAfter _start; // Holds the left boundry object TEIsBefore _end; // Holds the right boundry object /// Returns the DateTime on which this TE starts matching DateTime first() { return _first; } /// Returns the DateTime on which this TE stops matching DateTime last() { return _last; } /// Allow this class to be "stringified", this does not return the JSON string but does return a Map that can be stringified. Map toJson() { // Members to JSON list return({"TEMasterType": "TEInRange", "ValueAfter":_start.toJson(), "ValueBefore":_end.toJson()}); } /// Create a TEIs object from a Map object that was created manually (why?) or from the toJson method /// is a class factory TEInRange.fromJson(Map source) { if(source["TEMasterType"] != "TEInRange") { throw new InvalidJSONException("Invalid JSON Format: Not TEInRange"); } _start = new TEIsAfter.fromJson(source["ValueAfter"]); _end = new TEIsBefore.fromJson(source["ValueBefore"]); _first = _start.first(); _last = _end.last(); } /// Constructor to match all DateTimes between two given years. /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.Year(int startYear, int endYear, [bool startInclusive = true, bool endInclusive = true]) { _start = new TEIsAfter.Year(startYear, startInclusive); _end = new TEIsBefore.Year(endYear, endInclusive); _first =_start.first(); _last = _end.last(); } /// Constructor to match all DateTimes that occur between two given months, regardless of year. /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.Month(int startMonth, int endMonth, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.Month(startMonth, startInclusive); _end = new TEIsBefore.Month(endMonth, endInclusive); } /// Constructor to match all DateTimes that occur between two specific days of the week (Monday for example) regardless of year /// Uses the DateTime constants (DateTime.MONDAY) to select /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.DayOfWeek(int startDOW, int endDOW, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year, month, and week are undefined _last = null; _start = new TEIsAfter.DayOfWeek(startDOW, startInclusive); _end = new TEIsBefore.DayOfWeek(endDOW, endInclusive); } /// Constructor to match all DateTimes that occur between two specific days of every month (3rd of every month for example) regardless of year /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.DayOfMonth(int startDOM, int endDOM, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year and month are undefined _last = null; _start = new TEIsAfter.DayOfMonth(startDOM, startInclusive); _end = new TEIsBefore.DayOfMonth(endDOM, endInclusive); } /// Constructor to match all DateTimes that occur between two specific days of every year (day 212 of every year) /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.DayOfYear(int startDOY, int endDOY, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.DayOfYear(startDOY, startInclusive); _end = new TEIsBefore.DayOfYear(endDOY, endInclusive); } /// Constructor to match all DateTimes that occur between two specific hours of every day. /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.Hour(int startHour, int endHour, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.Hour(startHour, startInclusive); _end = new TEIsBefore.Hour(endHour, endInclusive); } /// Constructor to match all DateTimes that occur during two specific minutes of every hour; /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.Minute(int startMinute, int endMinute, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.Minute(startMinute, startInclusive); _end = new TEIsBefore.Minute(endMinute, endInclusive); } /// Constructor to match all DateTimes that occur between two specific seconds of every minute; /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.Second(int startSecond, int endSecond, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.Second(startSecond, startInclusive); _end = new TEIsBefore.Second(endSecond, startInclusive); } /// Constructor to match all DateTimes that occur between two specific milliseconds of every second; /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.Millisecond(int startMillisecond, int endMillisecond, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.Millisecond(startMillisecond, startInclusive); _end = new TEIsBefore.Millisecond(endMillisecond, startInclusive); } /// Constructor to match all dateTimes that occur during two specific weeks of the year. /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.WeekOfYear(int startWOY, int endWOY, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.WeekOfYear(startWOY, startInclusive); _end = new TEIsBefore.WeekOfYear(endWOY, endInclusive); } /// Constructor to match all DateTimes that occur after a given DateTime /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.DateTime(DateTime startDate, DateTime endDate, [bool startInclusive = true, bool endInclusive = true]) { _start = new TEIsAfter.DateTime(startDate, startInclusive); _end = new TEIsBefore.DateTime(endDate, endInclusive); _first = _start.first(); _last = _end.last(); } /// Constructor to match all DateTimes that occur after a given Date, ignoring any time component of the start and end DateTimes provided. /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.Date(DateTime startDate, DateTime endDate, [bool startInclusive = true, bool endInclusive = true]) { _start = new TEIsAfter.Date(startDate, startInclusive); _end = new TEIsBefore.Date(endDate, endInclusive); _first = _start.first(); _last = _end.last(); } /// Constructor to match all DateTimes that occur after a given Date, ignoring any time component of the start and end DateTimes provided. /// By default this is inclusive, but that can be changed with the boolean parameters. TEInRange.WeekOfMonth(int startDate, int endDate) { _start = new TEIsAfter.WeekOfMonth(startDate); _end = new TEIsBefore.WeekOfMonth(endDate); _first = _start.first(); _last = _end.last(); } /// Test to see if an arbitrary testDate is a match for this TE bool includes(DateTime testDate) { return _start.includes(testDate) && _end.includes(testDate); } }
Extends
TExpression > TEInRange
Constructors
new TEInRange.Date(DateTime startDate, DateTime endDate, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all DateTimes that occur after a given Date, ignoring any time component of the start and end DateTimes provided. By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.Date(DateTime startDate, DateTime endDate, [bool startInclusive = true, bool endInclusive = true]) { _start = new TEIsAfter.Date(startDate, startInclusive); _end = new TEIsBefore.Date(endDate, endInclusive); _first = _start.first(); _last = _end.last(); }
new TEInRange.DateTime(DateTime startDate, DateTime endDate, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all DateTimes that occur after a given DateTime By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.DateTime(DateTime startDate, DateTime endDate, [bool startInclusive = true, bool endInclusive = true]) { _start = new TEIsAfter.DateTime(startDate, startInclusive); _end = new TEIsBefore.DateTime(endDate, endInclusive); _first = _start.first(); _last = _end.last(); }
new TEInRange.DayOfMonth(int startDOM, int endDOM, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all DateTimes that occur between two specific days of every month (3rd of every month for example) regardless of year By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.DayOfMonth(int startDOM, int endDOM, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year and month are undefined _last = null; _start = new TEIsAfter.DayOfMonth(startDOM, startInclusive); _end = new TEIsBefore.DayOfMonth(endDOM, endInclusive); }
new TEInRange.DayOfWeek(int startDOW, int endDOW, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all DateTimes that occur between two specific days of the week (Monday for example) regardless of year Uses the DateTime constants (DateTime.MONDAY) to select By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.DayOfWeek(int startDOW, int endDOW, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year, month, and week are undefined _last = null; _start = new TEIsAfter.DayOfWeek(startDOW, startInclusive); _end = new TEIsBefore.DayOfWeek(endDOW, endInclusive); }
new TEInRange.DayOfYear(int startDOY, int endDOY, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all DateTimes that occur between two specific days of every year (day 212 of every year) By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.DayOfYear(int startDOY, int endDOY, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.DayOfYear(startDOY, startInclusive); _end = new TEIsBefore.DayOfYear(endDOY, endInclusive); }
new TEInRange.fromJson(Map source) #
Create a TEIs object from a Map object that was created manually (why?) or from the toJson method is a class factory
TEInRange.fromJson(Map source) { if(source["TEMasterType"] != "TEInRange") { throw new InvalidJSONException("Invalid JSON Format: Not TEInRange"); } _start = new TEIsAfter.fromJson(source["ValueAfter"]); _end = new TEIsBefore.fromJson(source["ValueBefore"]); _first = _start.first(); _last = _end.last(); }
new TEInRange.Hour(int startHour, int endHour, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all DateTimes that occur between two specific hours of every day. By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.Hour(int startHour, int endHour, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.Hour(startHour, startInclusive); _end = new TEIsBefore.Hour(endHour, endInclusive); }
new TEInRange.Millisecond(int startMillisecond, int endMillisecond, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all DateTimes that occur between two specific milliseconds of every second; By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.Millisecond(int startMillisecond, int endMillisecond, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.Millisecond(startMillisecond, startInclusive); _end = new TEIsBefore.Millisecond(endMillisecond, startInclusive); }
new TEInRange.Minute(int startMinute, int endMinute, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all DateTimes that occur during two specific minutes of every hour; By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.Minute(int startMinute, int endMinute, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.Minute(startMinute, startInclusive); _end = new TEIsBefore.Minute(endMinute, endInclusive); }
new TEInRange.Month(int startMonth, int endMonth, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all DateTimes that occur between two given months, regardless of year. By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.Month(int startMonth, int endMonth, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.Month(startMonth, startInclusive); _end = new TEIsBefore.Month(endMonth, endInclusive); }
new TEInRange.Second(int startSecond, int endSecond, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all DateTimes that occur between two specific seconds of every minute; By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.Second(int startSecond, int endSecond, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.Second(startSecond, startInclusive); _end = new TEIsBefore.Second(endSecond, startInclusive); }
new TEInRange.WeekOfMonth(int startDate, int endDate) #
Constructor to match all DateTimes that occur after a given Date, ignoring any time component of the start and end DateTimes provided. By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.WeekOfMonth(int startDate, int endDate) { _start = new TEIsAfter.WeekOfMonth(startDate); _end = new TEIsBefore.WeekOfMonth(endDate); _first = _start.first(); _last = _end.last(); }
new TEInRange.WeekOfYear(int startWOY, int endWOY, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all dateTimes that occur during two specific weeks of the year. By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.WeekOfYear(int startWOY, int endWOY, [bool startInclusive = true, bool endInclusive = true]) { _first = null; // first and last are null because year is undefined _last = null; _start = new TEIsAfter.WeekOfYear(startWOY, startInclusive); _end = new TEIsBefore.WeekOfYear(endWOY, endInclusive); }
new TEInRange.Year(int startYear, int endYear, [bool startInclusive = true, bool endInclusive = true]) #
Constructor to match all DateTimes between two given years. By default this is inclusive, but that can be changed with the boolean parameters.
TEInRange.Year(int startYear, int endYear, [bool startInclusive = true, bool endInclusive = true]) { _start = new TEIsAfter.Year(startYear, startInclusive); _end = new TEIsBefore.Year(endYear, endInclusive); _first =_start.first(); _last = _end.last(); }
Methods
Future<List<DateTime>> dates(DateTime baseDate, Duration interval, [int maxCount = 10, int maxIterations = 10000]) #
Returns the matching dates between the two dates defining the ranges
- Implemented as a Future which ultimately returns a List<DateTime> containing an ordered List of DateTime objects that meet the requirements
- The baseDate DateTime object is the point from which all future matches will be measured.
- The interval Duration is used to tell the method how much to increment each test by
- The optional maxCount parameter tells the method the maximum number of records to return (the method may return fewer, default 10)
- The maxIterations paramter sets the maximum number of attempts that the method will make to find the maxCount records requested. (default, 10000) if no matches are found before the maxIterations attempts expire.
Future<List<DateTime>> dates(DateTime baseDate, Duration interval, [int maxCount = 10, int maxIterations = 10000]) { Future<List<DateTime>> future = new Future(() { List<DateTime>response = new List<DateTime>(); bool complete = false; DateTime checkDate = baseDate; int results = maxCount; int iterations = maxIterations; while(complete == false) { // check to see if the check date is within scope if(_first != null) { if(checkDate.millisecondsSinceEpoch >= _first.millisecondsSinceEpoch) { // So now check to see if the date is included, if so, push to the results if(includes(checkDate)) { response.add(checkDate); results -= 1; } } } else { if(includes(checkDate)) { response.add(checkDate); results -= 1; } } checkDate = checkDate.add(interval); iterations -= 1; if(results <= 0 || iterations <= 0) { complete = true; } } return response; }); return future; }
int dayOfYear(DateTime date) #
Calculate what day of the year the provided DateTime sits on. This method handles leap year appropriately.
int dayOfYear(DateTime date) { int result = 0; int month = date.month; List<int> dayCounts = [0, 0,31,59,90,120,151,181,212,243,273,304,334]; result = dayCounts[month] + date.day; // This is to check to see if we need to add an extra day for leap year if(month > 2) { if(new DateTime(date.year, 3, 1, 0, 0, 0, -1).day == 29) { result += 1; } } return result; }
DateTime first() #
Returns the DateTime on which this TE starts matching
DateTime first() { return _first; }
bool includes(DateTime testDate) #
Test to see if an arbitrary testDate is a match for this TE
bool includes(DateTime testDate) { return _start.includes(testDate) && _end.includes(testDate); }
DateTime last() #
Returns the DateTime on which this TE stops matching
DateTime last() { return _last; }
int maxWeekOfMonth(DateTime date) #
Calculate the maximum week of the month that a date falls on Similar to weekOfMonth, this is a guess, there may be a more standard way to do thi It will always be between 1 and 6.
int maxWeekOfMonth(DateTime date) { DateTime monthStart = new DateTime(date.year, date.month, 1, 0, 0, 0, 0); DateTime lastDay = new DateTime(date.year, date.month + 1, 1, 0,0,0,-1); int lastWeek = weekOfYear(lastDay); int firstWeek = weekOfYear(monthStart); return (lastWeek - firstWeek + 1); }
Future<List<TEInRange>> openings(DateTime baseDate, Duration duration, Duration testResolution, Duration failResolution, Duration successResolution, [int maxCount = 10, int maxIterations = 10000]) #
This method is used to find available openings for scheduling events. A use case would be to find an opening for a two hour meeting on a calendar. This method takes several parameters that allow the programmer to control how the responses are calculated
- Implemented as a Future which ultimately returns a List of List<DateTime> containing an ordered List of start/end DateTime objects that meet the requirements
- The baseDate DateTime object is the point from which all future matches will be measured.
- The duration Duration is how long the gap we are looking for is.
- The testResolution is how frequently to test for collisions. This should be the smallest interval that can be scheduled.
- The failResolution is how for to space the next test if the current one fails.
- The successResolution is how far to space the next test once a hit is found. These allow us to ensure that we do not return 1000 ranges all starting 1ms apart.
- The optional maxCount parameter tells the method the maximum number of records to return (the method may return fewer, default 10)
- The maxIterations paramter sets the maximum number of attempts that the method will make to find the maxCount records requested. (default, 10000) if no matches are found before the maxIterations attempts expire.
Future<List<TEInRange>> openings(DateTime baseDate, Duration duration, Duration testResolution, Duration failResolution, Duration successResolution, [int maxCount = 10, int maxIterations = 10000]) { Future<List<TEInRange>> future = new Future(() { List<TEInRange> response = new List<TEInRange>(); bool complete = false; bool rangePass = true; DateTime startDate = baseDate; DateTime endDate = baseDate.add(duration); DateTime checkDate = baseDate; int results = maxCount; int iterations = maxIterations; // Keep going until the test is complete, it will end if: // * maxIterations limit is hit // * maxCount results are found // * The test start range is outside of the .first() .last() range. while(!complete) { iterations -= 1; checkDate = startDate; endDate = startDate.add(duration); rangePass = true; // See if the current range is passable while(rangePass && checkDate.isBefore(endDate)) { rangePass = includes(checkDate) ? true : false; checkDate = checkDate.add(testResolution); } if(rangePass) { response.add(new TEInRange.DateTime(startDate, startDate.add(duration))); startDate = startDate.add(successResolution); results -= 1; } else { startDate = startDate.add(failResolution); } // Here are the tests for completion if(results <= 0 || iterations <= 0 || startDate.millisecondsSinceEpoch > last().millisecondsSinceEpoch) { complete = true; } } return response; }); return future; }
Map toJson() #
Allow this class to be "stringified", this does not return the JSON string but does return a Map that can be stringified.
Map toJson() { // Members to JSON list return({"TEMasterType": "TEInRange", "ValueAfter":_start.toJson(), "ValueBefore":_end.toJson()}); }
int type() #
Return the type code for this TE, will be one of the above defined constants or -1 (TExpression.UNDEFINED) if not properly set.
int type() { return _teType; }
int weekOfMonth(DateTime date) #
Calculate the week of the month that a date falls on This is a wild guess as to the best way to calculate this It will always start at 1 and go as high as 6
int weekOfMonth(DateTime date) { DateTime monthStart = new DateTime(date.year, date.month, 1, 0, 0, 0, 0); int startWeek = weekOfYear(monthStart); int endWeek = weekOfYear(date); return (endWeek - startWeek + 1); }
int weekOfYear(DateTime date) #
Calculate what week of the year the provided DateTime is in, as defined in ISO8601. The Dart DateTime library is also based on ISO8601, as a result the following conventions apply: Weeks begin on MONDAY, not SUNDAY as in some calendar implementations The first week of the year is defined as that which includes January 4th. As a result, the first one to three days may be included in the last week of the previous year. If that is the case, this function returns that week as 0.
int weekOfYear(DateTime date) { int dowJan4 = new DateTime(date.year,1,4,0,0,0,0).weekday; return ((dowJan4 + dayOfYear(date) + 2) ~/ 7); }