TEIsAfter class
The Is TE provides funcationality to test for occurrences after a deadline of the various DateTime components such as Year, Month, etc.
class TEIsAfter extends TExpression { DateTime _first; // The first DateTime that matches this TE DateTime _last; // The last DateTime that matches this TE (inclusive) int _teType; // Keeps track of the "type" of TE that we are tracking bool _inclusive; // Is true if this range is inclusive, false otherwise var _value; // Holds the value used for testing var _paramValue; // Holds the value provided in the constructor /// 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() { if(_value is int) { return ({"TEMasterType": "TEIsAfter", "TEType": _teType, "Inclusive": _inclusive, "Value": _paramValue}); } else if(_value is DateTime) { return({"TEMasterType": "TEIsAfter", "TEType": _teType, "Inclusive": _inclusive, "Value": {"TEMasterType":"DateTime", "Value": _paramValue.millisecondsSinceEpoch}}); } } /// Create a TEIs object from a Map object that was created manually (why?) or from the toJson method /// is a class factory factory TEIsAfter.fromJson(Map source) { var value = source["Value"]; bool inclusive = source["Inclusive"]; TEIsAfter result; if(value is Map) { value = new DateTime.fromMillisecondsSinceEpoch(value["Value"], isUtc: true); } switch(source["TEType"]) { case TExpression.YEAR: result = new TEIsAfter.Year(value,inclusive); break; case TExpression.MONTH: result = new TEIsAfter.Month(value,inclusive); break; case TExpression.DATETIME: result = new TEIsAfter.DateTime(value,inclusive); break; case TExpression.DAYOFWEEK: result = new TEIsAfter.DayOfWeek(value,inclusive); break; case TExpression.DAYOFMONTH: result = new TEIsAfter.DayOfMonth(value,inclusive); break; case TExpression.WEEKOFYEAR: result = new TEIsAfter.WeekOfYear(value,inclusive); break; case TExpression.DAYOFYEAR: result = new TEIsAfter.DayOfYear(value,inclusive); break; case TExpression.HOUR: result = new TEIsAfter.Hour(value,inclusive); break; case TExpression.MINUTE: result = new TEIsAfter.Minute(value,inclusive); break; case TExpression.SECOND: result = new TEIsAfter.Second(value,inclusive); break; case TExpression.MILLISECOND: result = new TEIsAfter.Millisecond(value,inclusive); break; case TExpression.DATE: result = new TEIsAfter.Date(value,inclusive); break; case TExpression.WEEKOFMONTH: result = new TEIsAfter.WeekOfMonth(value); break; } return result; } /// Constructor to match all DateTimes before given year. /// By default this is inclusive, but that can be changed with the second boolean parameter. TEIsAfter.Year(int year, [bool inclusive = true]) { _inclusive = inclusive; _value = year; _paramValue = year; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one _first = new DateTime.utc(_value + 1, 1, 1, 0, 0, 0, 0); _last = null; _teType = TExpression.YEAR; } /// Constructor to match all DateTimes that occur in a given month, regardless of year. TEIsAfter.Month(int month, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.MONTH; _value = month; _paramValue = month; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one } /// Constructor to match all DateTimes that occur on a specific day of the week (Monday for example) regardless of year /// Uses the DateTime constants (DateTime.MONDAY) to select TEIsAfter.DayOfWeek(int day, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year, month, and week are undefined _last = null; _teType = TExpression.DAYOFWEEK; _value = day; _paramValue = day; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one } /// Constructor to match all DateTimes that occur on a specific day of every month (3rd of every month for example) regardless of year TEIsAfter.DayOfMonth(int day, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year and month are undefined _last = null; _teType = TExpression.DAYOFMONTH; _value = day; _paramValue = day; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one } /// Constructor to match all DateTimes that occur on a specific day of every year (day 212 of every year) TEIsAfter.DayOfYear(int day, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.DAYOFYEAR; _value = day; _paramValue = day; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one } /// Constructor to match all DateTimes that occur during a specific hour of every day. TEIsAfter.Hour(int hour, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.HOUR; _value = hour; _paramValue = hour; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one } /// Constructor to match all DateTimes that occur during a specific minute of every hour; TEIsAfter.Minute(int minute, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.MINUTE; _value = minute; _paramValue = minute; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one } /// Constructor to match all DateTimes that occur during a specific second of every minute; TEIsAfter.Second(int second, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.SECOND; _value = second; _paramValue = second; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one } /// Constructor to match all DateTimes that occur during a specific millisecond of every second; TEIsAfter.Millisecond(int millisecond, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.MILLISECOND; _value = millisecond; _paramValue = millisecond; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one } /// Constructor to match all dateTimes that occur during a specific week of the year. TEIsAfter.WeekOfYear(int week, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.WEEKOFYEAR; _value = week; _paramValue = week; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one } /// Constructor to match all DateTimes that occur after a given Date TEIsAfter.DateTime(DateTime date, [bool inclusive = true]) { _first = date; _last = null; _inclusive = inclusive; _teType = TExpression.DATETIME; _value = date; _paramValue = date; if(inclusive == true) { _value = _value.subtract(new Duration(milliseconds:1)); } else { _first = _first.add(new Duration(milliseconds:1)); } } /// Constructor to match all DateTimes that occur after a specific day (ignoring supplied time parameters provided (if any) supplied in the DateTime TEIsAfter.Date(DateTime date, [bool inclusive = true]) { _first = new DateTime.utc(date.year, date.month, date.day,0,0,0,0); _last = null; _inclusive = inclusive; _teType = TExpression.DATE; _value = date; _paramValue = date; if(inclusive == true) { _value = _value.subtract(new Duration(milliseconds:1)); } else { _first = _first.add(new Duration(hours:24)); } } /// Constructor to match all weeks after a given week of a month. /// Positive values indicate a count starting from the beginning of the month /// Negative values indicate a count starting from the end of the month. /// This TI is always inclusive; /// A value of 0 will return false TEIsAfter.WeekOfMonth(int week) { _first = null; _last = null; _inclusive = true; _teType = TExpression.WEEKOFMONTH; _value = week; _paramValue = week; } /// Test to see if an arbitrary testDate is a match for this TE bool includes(DateTime testDate) { bool result = false; switch(_teType) { case TExpression.YEAR: result = testDate.year > _value; break; case TExpression.MONTH: result = testDate.month > _value; break; case TExpression.DATETIME: result = testDate.isAfter(_value); break; case TExpression.DAYOFWEEK: result = testDate.weekday > _value; break; case TExpression.WEEKOFYEAR: result = weekOfYear(testDate) > _value; break; case TExpression.DAYOFMONTH: result = testDate.day > _value; break; case TExpression.DAYOFYEAR: result = dayOfYear(testDate) > _value; break; case TExpression.HOUR: result = testDate.hour > _value; break; case TExpression.MINUTE: result = testDate.minute > _value; break; case TExpression.SECOND: result = testDate.second > _value; break; case TExpression.MILLISECOND: result = testDate.millisecond > _value; break; case TExpression.DATE: result = testDate.millisecondsSinceEpoch > _value.millisecondsSinceEpoch; break; case TExpression.WEEKOFMONTH: result = false; int testWOM = weekOfMonth(testDate); if(_value == 0) { result = false; } else if(_value >= 0) { result = _value <= testWOM; } else { int maxWOM = maxWeekOfMonth(testDate); result = ((maxWOM + _value) + 1) <= testWOM; } break; } return result; } }
Extends
TExpression > TEIsAfter
Constructors
new TEIsAfter.Date(DateTime date, [bool inclusive = true]) #
Constructor to match all DateTimes that occur after a specific day (ignoring supplied time parameters provided (if any) supplied in the DateTime
TEIsAfter.Date(DateTime date, [bool inclusive = true]) { _first = new DateTime.utc(date.year, date.month, date.day,0,0,0,0); _last = null; _inclusive = inclusive; _teType = TExpression.DATE; _value = date; _paramValue = date; if(inclusive == true) { _value = _value.subtract(new Duration(milliseconds:1)); } else { _first = _first.add(new Duration(hours:24)); } }
new TEIsAfter.DateTime(DateTime date, [bool inclusive = true]) #
Constructor to match all DateTimes that occur after a given Date
TEIsAfter.DateTime(DateTime date, [bool inclusive = true]) { _first = date; _last = null; _inclusive = inclusive; _teType = TExpression.DATETIME; _value = date; _paramValue = date; if(inclusive == true) { _value = _value.subtract(new Duration(milliseconds:1)); } else { _first = _first.add(new Duration(milliseconds:1)); } }
new TEIsAfter.DayOfMonth(int day, [bool inclusive = true]) #
Constructor to match all DateTimes that occur on a specific day of every month (3rd of every month for example) regardless of year
TEIsAfter.DayOfMonth(int day, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year and month are undefined _last = null; _teType = TExpression.DAYOFMONTH; _value = day; _paramValue = day; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one }
new TEIsAfter.DayOfWeek(int day, [bool inclusive = true]) #
Constructor to match all DateTimes that occur on a specific day of the week (Monday for example) regardless of year Uses the DateTime constants (DateTime.MONDAY) to select
TEIsAfter.DayOfWeek(int day, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year, month, and week are undefined _last = null; _teType = TExpression.DAYOFWEEK; _value = day; _paramValue = day; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one }
new TEIsAfter.DayOfYear(int day, [bool inclusive = true]) #
Constructor to match all DateTimes that occur on a specific day of every year (day 212 of every year)
TEIsAfter.DayOfYear(int day, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.DAYOFYEAR; _value = day; _paramValue = day; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one }
factory TEIsAfter.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
factory TEIsAfter.fromJson(Map source) { var value = source["Value"]; bool inclusive = source["Inclusive"]; TEIsAfter result; if(value is Map) { value = new DateTime.fromMillisecondsSinceEpoch(value["Value"], isUtc: true); } switch(source["TEType"]) { case TExpression.YEAR: result = new TEIsAfter.Year(value,inclusive); break; case TExpression.MONTH: result = new TEIsAfter.Month(value,inclusive); break; case TExpression.DATETIME: result = new TEIsAfter.DateTime(value,inclusive); break; case TExpression.DAYOFWEEK: result = new TEIsAfter.DayOfWeek(value,inclusive); break; case TExpression.DAYOFMONTH: result = new TEIsAfter.DayOfMonth(value,inclusive); break; case TExpression.WEEKOFYEAR: result = new TEIsAfter.WeekOfYear(value,inclusive); break; case TExpression.DAYOFYEAR: result = new TEIsAfter.DayOfYear(value,inclusive); break; case TExpression.HOUR: result = new TEIsAfter.Hour(value,inclusive); break; case TExpression.MINUTE: result = new TEIsAfter.Minute(value,inclusive); break; case TExpression.SECOND: result = new TEIsAfter.Second(value,inclusive); break; case TExpression.MILLISECOND: result = new TEIsAfter.Millisecond(value,inclusive); break; case TExpression.DATE: result = new TEIsAfter.Date(value,inclusive); break; case TExpression.WEEKOFMONTH: result = new TEIsAfter.WeekOfMonth(value); break; } return result; }
new TEIsAfter.Hour(int hour, [bool inclusive = true]) #
Constructor to match all DateTimes that occur during a specific hour of every day.
TEIsAfter.Hour(int hour, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.HOUR; _value = hour; _paramValue = hour; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one }
new TEIsAfter.Millisecond(int millisecond, [bool inclusive = true]) #
Constructor to match all DateTimes that occur during a specific millisecond of every second;
TEIsAfter.Millisecond(int millisecond, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.MILLISECOND; _value = millisecond; _paramValue = millisecond; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one }
new TEIsAfter.Minute(int minute, [bool inclusive = true]) #
Constructor to match all DateTimes that occur during a specific minute of every hour;
TEIsAfter.Minute(int minute, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.MINUTE; _value = minute; _paramValue = minute; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one }
new TEIsAfter.Month(int month, [bool inclusive = true]) #
Constructor to match all DateTimes that occur in a given month, regardless of year.
TEIsAfter.Month(int month, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.MONTH; _value = month; _paramValue = month; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one }
new TEIsAfter.Second(int second, [bool inclusive = true]) #
Constructor to match all DateTimes that occur during a specific second of every minute;
TEIsAfter.Second(int second, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.SECOND; _value = second; _paramValue = second; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one }
new TEIsAfter.WeekOfMonth(int week) #
Constructor to match all weeks after a given week of a month. Positive values indicate a count starting from the beginning of the month Negative values indicate a count starting from the end of the month. This TI is always inclusive; A value of 0 will return false
TEIsAfter.WeekOfMonth(int week) { _first = null; _last = null; _inclusive = true; _teType = TExpression.WEEKOFMONTH; _value = week; _paramValue = week; }
new TEIsAfter.WeekOfYear(int week, [bool inclusive = true]) #
Constructor to match all dateTimes that occur during a specific week of the year.
TEIsAfter.WeekOfYear(int week, [bool inclusive = true]) { _inclusive = inclusive; _first = null; // first and last are null because year is undefined _last = null; _teType = TExpression.WEEKOFYEAR; _value = week; _paramValue = week; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one }
new TEIsAfter.Year(int year, [bool inclusive = true]) #
Constructor to match all DateTimes before given year. By default this is inclusive, but that can be changed with the second boolean parameter.
TEIsAfter.Year(int year, [bool inclusive = true]) { _inclusive = inclusive; _value = year; _paramValue = year; if(inclusive == true) { _value -= 1; }; // All tests are non inclusive so if it needs to be inclusive subtract one _first = new DateTime.utc(_value + 1, 1, 1, 0, 0, 0, 0); _last = null; _teType = TExpression.YEAR; }
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) { bool result = false; switch(_teType) { case TExpression.YEAR: result = testDate.year > _value; break; case TExpression.MONTH: result = testDate.month > _value; break; case TExpression.DATETIME: result = testDate.isAfter(_value); break; case TExpression.DAYOFWEEK: result = testDate.weekday > _value; break; case TExpression.WEEKOFYEAR: result = weekOfYear(testDate) > _value; break; case TExpression.DAYOFMONTH: result = testDate.day > _value; break; case TExpression.DAYOFYEAR: result = dayOfYear(testDate) > _value; break; case TExpression.HOUR: result = testDate.hour > _value; break; case TExpression.MINUTE: result = testDate.minute > _value; break; case TExpression.SECOND: result = testDate.second > _value; break; case TExpression.MILLISECOND: result = testDate.millisecond > _value; break; case TExpression.DATE: result = testDate.millisecondsSinceEpoch > _value.millisecondsSinceEpoch; break; case TExpression.WEEKOFMONTH: result = false; int testWOM = weekOfMonth(testDate); if(_value == 0) { result = false; } else if(_value >= 0) { result = _value <= testWOM; } else { int maxWOM = maxWeekOfMonth(testDate); result = ((maxWOM + _value) + 1) <= testWOM; } break; } return result; }
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() { if(_value is int) { return ({"TEMasterType": "TEIsAfter", "TEType": _teType, "Inclusive": _inclusive, "Value": _paramValue}); } else if(_value is DateTime) { return({"TEMasterType": "TEIsAfter", "TEType": _teType, "Inclusive": _inclusive, "Value": {"TEMasterType":"DateTime", "Value": _paramValue.millisecondsSinceEpoch}}); } }
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); }