print first monday of every week of current month Flutter/Dart - flutter

I have a calendar in my Flutter App and I need to print a list of the weeks in the current month. But rather than starting on the 1st day of each month, it needs to start with the first Monday of the month (e.g. 05 April 2021 as the first Monday of April 2021). Then I need to print out the following weeks in that month, again starting from Monday. This includes the days of the next month that the final week of the current month follows on from (e.g. 26 April 2021 - 02 May 2021). It should print like this:
05 Apr - 11 Apr
12 Apr - 18 Apr
19 Apr - 25 Apr
26 Apr - 02 May

Start by figuring out how to find how many days there are from a given weekday to the Monday on or after that day. Examples help; if the given weekday is:
Monday, add 0 days.
Tuesday, add 6 days.
Wednesday, add 5 days.
... etc. ...
Sunday, add 1 day.
We could make a lookup table, but we also can devise that the offset (in days) from a given weekday to the Monday on or after that day has the form (7 - x) % 7
where x corresponds to the given weekday. We'd want that value to be 0 for Monday, 1 for Tuesday, and so on, until 6 for Sunday. Dart's DateTime.weekday uses values 1 (DateTime.monday) through 7 (DateTime.sunday), so we can easily map that to the value we want via DateTime.weekday - DateTime.monday.
Once we compute that offset, we can find the first day of the current month, add that offset to find the first Monday of the month, and then you can iteratively add 7 days until you reach the next month, and we can use DateFormat from package:intl to format the dates the way you want:
import 'package:intl/intl.dart';
String formatDate(DateTime dateTime) => DateFormat('dd MMM').format(dateTime);
void main() {
var now = DateTime.now();
var firstOfMonth = DateTime(now.year, now.month, 1);
var firstMonday =
firstOfMonth.addCalendarDays((7 - (firstOfMonth.weekday - DateTime.monday)) % 7);
var currentMonday = firstMonday;
while (currentMonday.month == now.month) {
var nextMonday = currentMonday.addCalendarDays(7);
var nextSunday = nextMonday.addCalendarDays(-1);
print('${formatDate(currentMonday)} - ${formatDate(nextSunday)}');
currentMonday = nextMonday;
}
}
See https://stackoverflow.com/a/68216029/ for the implementation of the addCalendarDays extension method.

Related

How to calculate days between two dates only if they belong to a certain month

For example the date range is
28-01-2022 and 20-03-2022
I want to count separately the days that belong to january (3) february (27) and march (19)
I would really appreciate the help!!
In python, you can do the following:
import calendar
import datetime
from dateutil import relativedelta
start_str = "1-03-2022"
end_str = "20-12-2024"
start = datetime.datetime.strptime(start_str, "%d-%m-%Y")
end = datetime.datetime.strptime(end_str, "%d-%m-%Y")
days = []
while start.year <= end.year and start.month <= end.month:
if start.year == end.year and start.month == end.month:
days.append(end.day - start.day)
else:
days.append(calendar.monthrange(
start.year, start.month)[1]-start.day+1)
start = start.replace(day=1)
start += relativedelta.relativedelta(months=1)
print(*days)
This includes the start day and excludes the end date, meaning that in your example, 4 days belong to January and 19 to March. Does February have 27 days only?

Moment js validating edge case, dates like feb 30th [duplicate]

This question already has answers here:
Calculate days to go until a particular date with momentjs
(3 answers)
Closed 1 year ago.
I want to validate if the following date is valid : 30 Feb 2021.
So the main issue is 30 Feb 2021 shouldn't be a valid date or 31 April 2021. is it possible to achieve that with moment js or luxon? or should i use another approach?
let m = moment([2021, 2, 31]);
console.log("Date is valid", m.isValid()); \\returns true which is not a valid date!
I don't know moment.js or luxon , but it's achievable in basic JS (although a little long-winded)
JavaScript will up-tick the date, so the 29th of Feb is the 1st of March.
Therefore we can compare the before and after version :
var month = 1; // zero based - 1 is feb
var day = 30;
var year = 2021;
var testDate = new Date(year, month, day); // will convert to 2nd of March
var parsedDate = testDate.getDate(); // will be 2
var parsedMonth = testdate.getMonth() // will be 2 , zero based, March
var parsedYear = testDate.getFullYear(); // remains 2021 in this case
var isValidDate = parsedDate === day && parsedMonth === month && parsedYear === year;
This could be condensed a lot but I've made it as bloated as possible for readability
you could easily turn it into a function, something like this (untested)
function IsValidDate(year, month, day){
var InputMonthsAreOneBased = 0; // change to 1 if needed
var testDate = new Date(year, month - InputMonthsAreOneBased, day );
return testDate.getDate() === day && testdate.getMonth() === (month - InputMonthsAreOneBased) && testDate.getFullYear() === year;
}

Swift Number Of Weeks in Month

I'm using Swift 5. I'm trying to get the number of weeks in a month. Jan 2021 prints 6 weeks, but May prints 5 weeks. I'm thinking the problem is firstWeekday is set to 1. Is there a way to get the number of weeks in a given month without setting firstWeekday?
var localCalendar = Calendar.current
localCalendar.firstWeekday = 1
let weekRange = localCalendar.range(of: .weekOfMonth, in: .month, for: dateFormatter.date(from: monthName)!)
if let weekRange = weekRange {
print("\(monthName) has \(weekRange.count) weeks.")
}
It seems you do not want the number of weeks in a month at all. You want the number of rows in a calendar printout.
The formula for the number of rows needed to represent a month on a standard Gregorian-style calendar is as follows.
Start with the number of days in the month. Add to that the number of blank days before the start of the month, beginning with Sunday. For example, January 2021 is 31 + 5 = 36, because it's 31 days long but 5 days (Sunday thru Thursday) are not part of it before the start. To put it another way: the first day of January 2021 is a Friday; that is day 5 of the week if we call Sunday day 0, so we get 31 + 5.
Now integer-divide by 7. We need at least that number of rows. So (31+5)/7 using integer division is 5. The question is: is that all the rows we need?
To find out, get the remainder of that division. If it is not zero, add another row. So (31+5)%7 is 1, which tells us that one more day needs to be accommodated so we need another row. That makes 6.
Thus:
// `startingOn` pretends that Sunday is day 0
func rowsNeededForMonthWith(numberOfDays n: Int, startingOn i: Int) -> Int {
let (quot,rem) = (n+i).quotientAndRemainder(dividingBy: 7)
return quot + (rem == 0 ? 0 : 1)
}
Here are some quick sanity tests:
// January 2021
rowsNeededForMonthWith(numberOfDays: 31, startingOn: 5) // 6
// But suppose it had 30 days?
rowsNeededForMonthWith(numberOfDays: 30, startingOn: 5) // 5
// Or suppose it had started on Thursday? (cf July 2021)
rowsNeededForMonthWith(numberOfDays: 31, startingOn: 4) // 5

D3.js - get number of days for a certain month

I'm using D3.js (v3) to plot a time-series graph and I'm trying to figure out the amount of ticks I need for a given month (ie, days). From what I can make of the documentation, d3.time-month should return something from 28 to 31 days, which is what I want, but for some reason I'm obviously missing, I can't seem to get the number I need.
Can anyone help?
This is what I've got so far:
console.log(date); // Fri Jul 01 2016 00:00:00 GMT+0100 (WEST)
monthDays = d3.time.month(date);
console.log(currentMonth+" has "+monthDays+" days."); // July has Fri Jul 01 2016 00:00:00 GMT+0100 (WEST) days.
You're misreading the documentation on intervals : the number of days in the intervals used by d3.time.month have a length between 28 and 31 but the functions are defined as
interval(date)
Alias for interval.floor(date). [...]
and
interval.floor(date)
Rounds down the specified date, returning the latest time interval
before or equal to date. [...]
Basically, d3.time.month(date) will return the first day of the month at midnight, not the number of days in that month.
How to get the number of days then? As far as I can tell, D3 does not expose a way to get the length of the month for a given date. You could of course get the range of days for a given month and extract its length:
var date = new Date(2016, 01, 02); // 2016-02-02
console.log(
d3.time.days(d3.time.month(date), d3.time.month.ceil(date)).length
)
or probably more efficiently use plain JS like in this answer https://stackoverflow.com/a/1185804/1071630 :
var date = new Date(2016, 01, 02); // 2016-02-02
console.log(
new Date(date.getFullYear(), date.getMonth()+1, 0).getDate()
)
var date = new Date(2016, 01, 02);
console.log(
d3.time.days(d3.time.month(date), d3.time.month.ceil(date)).length
)
console.log(
new Date(date.getFullYear(), date.getMonth()+1, 0).getDate()
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

how can i get the day of the week for a particular given date in Matlab

As today is Wednesday with date June 8, 2016. how can i write a code to get the day of given dates:
like what day is Nov 29
I'm trying to create a struct with
date
day
month
with month and date as input
Use the builtin weekday() function:
>> [num, name] = weekday('08-Jun-2016')
num =
4
name =
Wed
>> [num, name] = weekday('29-Nov-2016')
num =
3
name =
Tue
In addition to the weekday function, you can use the DDD or DDDD formats in the datestr function, like this:
datestr('08-Jun-2016','DDD') %Returns the string 'Wed'
datestr('08-Jun-2016','DDDD') %Returns the string 'Wednesday'
Or, to use a more practical format
datestr('08-Jun-2016','DDDD, mmmm DD, yyyy')
% Returns the string: 'Wednesday, June 08, 2016'