How to calculate period between a specific date? - flutter

I'm studying Flutter and in my application I need to calculate how many days are left until the 17th of the next month. There is no way to have a specific date, so it would be crucial to have today's date and add 1 month and calculate how many days are left.
For example: Today is 2021-09-09 and there are 38 days to 2021-10-17. The function does not calculate the 17th of the current month, but the following month.
Any idea how to make a function that takes the current date, adds 1 month and calculates how many days are left until the 17th? Thanks.

Basically copy the DateTime object with 1 added to the current month number and the day set to the 17th. Then subtract the two DateTime objects and convert the resulting Duration to days. It's important to perform all calculations in UTC so that Daylight Saving Time adjustments aren't a factor.
/// Returns the number of days to the specified [day] in the month following
/// [startDate].
int daysToNextMonthDay(DateTime startDate, int day) {
// Recreate `startDate` as a UTC `DateTime`. We don't care about the
// time.
//
// Note that this isn't the same as `startDate.toUtc()`. We want a UTC
// `DateTime` with specific values, not necessarily the UTC time
// corresponding to same moment as `startDate`.
startDate = DateTime.utc(startDate.year, startDate.month, startDate.day);
var nextMonthDay = DateTime.utc(startDate.year, startDate.month + 1, day);
// Verify that the requested day exists in the month.
if (nextMonthDay.day != day) {
throw ArgumentError(
'Day $day does not exist for the month following ${startDate.month}',
);
}
return nextMonthDay.difference(startDate).inDays;
}
void main() {
var now = DateTime(2021, 9, 9);
print(daysToNextMonthDay(now, 17)); // Prints: 38
}

try this:
void main() {
DateTime date = DateTime.now();
print(daysLeft(date.subtract(Duration(days: 1))));
}
bool isLeapYear(int year) {
if (year % 4 == 0) {
if (year % 100 == 0) {
if (year % 400 == 0) {
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
int daysLeft(DateTime date){
int daysLeft = 0;
switch(date.month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: daysLeft = 31 - date.day + 17; break;
case 4:
case 6:
case 9:
case 11: daysLeft = 30 - date.day + 17; break;
case 2: if(isLeapYear(date.year)){
daysLeft = 29 - date.day + 17;
break;
}else{
daysLeft = 28 - date.day + 17;
}
}
return daysLeft;
}

Related

Calculating dates excluding weekends in Flutter

I'm trying to calculate the number of days between a range excluding weekends. The code that I've come up with right now excludes only Saturdays but not Sundays. For instance, my code returns 1 instead of 0 when the start and end dates are 24-SEP-2022(Saturday) and 25-SEP-2022(Sunday). Similarly, 25-SEP-2022(Sunday) and 26-SEP-2022(Monday) returns 2 when they should have returned 1.
Here is my code:
String method(String start, String end) {
int a = 1;
DateTime startDate = DateTime.parse(start);
DateTime endDate = DateTime.parse(end);
while (startDate.isBefore(endDate)) {
startDate = startDate.add(const Duration(days: 1));
if (startDate.weekday != DateTime.saturday &&
startDate.weekday != DateTime.sunday) {
a++;
}
}
print('COUNT: $start :: $end $a');
return a.toString();
}
Any help would be appreciated!
You did not pay attention to a! You have initiated a = 1, but in this case it has to be 0. because of that it always returns one more day.

How to select a week(custom) in the Flutter Date Range Picker (SfDateRangePicker)

I try to implement a weekly selector by following this example - https://www.syncfusion.com/kb/11412/how-to-select-a-week-in-the-flutter-date-range-picker-sfdaterangepicker
The problem I encounter is that the "args.value" from DateRangePickerSelectionChangedArgs returns a date range from Sunday to Saturday. What I want is for the DateRangePickerSelectionChangedArgs to return a date range from Monday to Sunday. I want the weekly selector to select the whole week from Monday to Sunday not from Sunday to Saturday as shown in this screenshot.
enter image description here
I try the codes below. I tried adding one to the start date and to the end date so that Sunday becomes Monday and Saturday becomes Sunday, but the code didn't work when I did that.
void selectionChanged(DateRangePickerSelectionChangedArgs args) {
isSameDate(date1, date2) {
if (date2 == date1) {
return true;
}
if (date1 == null || date2 == null) {
return false;
}
return date1.month == date2.month && date1.year == date2.year && date1.day == date2.day;
}
int firstDayOfWeek = DateTime.sunday % 7;
int endDayOfWeek = (firstDayOfWeek - 1) % 7;
endDayOfWeek = endDayOfWeek < 0 ? 7 + endDayOfWeek : endDayOfWeek;
PickerDateRange ranges = args.value;
DateTime date1 = ranges.startDate!;
DateTime date2 = (ranges.endDate ?? ranges.startDate)!;
if (date1.isAfter(date2)) {
var date = date1;
date1 = date2;
date2 = date;
}
int day1 = date1.weekday % 7;
int day2 = date2.weekday % 7;
DateTime dat1 = date1.add(Duration(days: (firstDayOfWeek - day1) + 1));
DateTime dat2 = date2.add(Duration(days: (endDayOfWeek - day2) + 1));
if (!isSameDate(dat1, date1) || !isSameDate(dat2, date2)) {
datePickerController.selectedRange = PickerDateRange(dat1, dat2);
}
}
You can customize the first day of the week in the date range picker by using the FirstDayofWeek property from the MonthViewSettings. Refer to the UG documentation to know more about FirstDayofWeek,
https://help.syncfusion.com/flutter/daterangepicker/getting-started#change-first-day-of-week
Refer to the code snippets to achieve your requirement,

how to create a 30 minutes timeslot.. Im getting the start date and end date from backend

List<WorkingHourModel> workingHours = response['hours'];
int startTime = int.parse(workingHours[0].startTime.split(':')[0]);
int endTime = int.parse(workingHours[0].endTime.split(':')[0]);
int hoursLeft = endTime - startTime + 1;
List<String> hours =
List.generate(hoursLeft, (i) => '${(endTime - i)}:00').reversed
.toList();
print('Hours-------- $hours');
return {
'success': true,
'hours': hours,
};
}
//this will give the time slots as '1:00', '2:00', '3:00', '4:00'
//Start time will be 1:00 and end time will be 4:00.
Heading
But i need 30 mins breakage, like,
'1:00', '1:30', '2:00', '2:30', '3:00', '3:30', '4:00'
Kindly help..
This should generate the list as you want it:
void main(List<String> args) {
// lets assume 9 to 5
int startTime = 9;
int endTime = 17;
int hoursLeft = endTime - startTime + 1;
final hours = List.generate(hoursLeft * 2, (i) => '${endTime - (i/2).truncate()}:${i%2 == 1 ? '00' : '30'}').reversed.toList();
print('Hours-------- $hours');
}
Hours-------- [9:00, 9:30, 10:00, 10:30, 11:00, 11:30, 12:00, 12:30, 13:00, 13:30, 14:00, 14:30, 15:00, 15:30, 16:00, 16:30, 17:00, 17:30]
Generally speaking, if you have more complicated calculations (what happens if someone works 18:00 to 05:00 in the nightshift?) you may want to use the proper datatypes instead of integers and string concatenation.

How many weeks in a month with X weekday in them?

I'm looking for a way to get the number of weeks with X weekday in them a month has. For example:- How many weeks are there in march with Wednesday in them? Answer - 5.
I would be happy with a general answer but it would be great to know if there's an efficient way to do that using dart. Thank you.
Try this...
int weeksCountOfWeekday(int weekdayToCnt, int month, int year) {
assert(weekdayToCnt >= 1 && weekdayToCnt <= 7);
final DateTime startDate = DateTime(year, month);
final DateTime endDate =
DateTime(year, month + 1).subtract(const Duration(days: 1));
int res = 1;
int dayOfWeekday;
if (weekdayToCnt < startDate.weekday) {
dayOfWeekday = startDate.day + 7 - (startDate.weekday - weekdayToCnt);
} else {
dayOfWeekday = 1 + weekdayToCnt - startDate.weekday;
}
while (dayOfWeekday + 7 <= endDate.day) {
res++;
dayOfWeekday += 7;
}
return res;
}

How do you format the day of the month to say “11th”, “21st” or “23rd” in Dart?

I have a date and want to display the date with the suffix th, st, rd, etc.
Here is my dart code.
int year = date.year;
int month = date.month;
int day = date.day;
DateTime dateSelected = new DateTime(year, month, day);
var formatter = new DateFormat('EEEE MMMM dd, yyyy');
displayDate = formatter.format(dateSelected);
This displays dates as "Wednesday April 23, 2014" for example, but I need "Wednesday April 23rd, 2014".
I'm using the intl package.
import 'package:intl/intl.dart';
String getDayOfMonthSuffix(int dayNum) {
if(!(dayNum >= 1 && dayNum <= 31)) {
throw Exception('Invalid day of month');
}
if(dayNum >= 11 && dayNum <= 13) {
return 'th';
}
switch(dayNum % 10) {
case 1: return 'st';
case 2: return 'nd';
case 3: return 'rd';
default: return 'th';
}
}
The above method gets the suffix for you. You can use string concatenation or string interpolation to put together the format you want. e.g
'$day ${getDayOfMonthSuffix(day)}'
Try out this package, Jiffy, inspired by momentjs.
Just simply add the do date pattern. See below
Jiffy([2014, 4, 23]).format("EEEE MMMM do, yyyy"); // Wednesday April 23rd, 2014
You can also add your DateTime object
Jiffy(DateTime(2014, 4, 23)).format("EEEE MMMM do, yyyy"); // Wednesday April 23rd, 2014
I don’t think that there’s build-in functionality for that. You could format the date like that:
format(DateTime date) {
var suffix = "th";
var digit = date.day % 10;
if ((digit > 0 && digit < 4) && (date.day < 11 || date.day > 13)) {
suffix = ["st", "nd", "rd"][digit - 1];
}
return new DateFormat("EEEE MMMM d'$suffix', yyyy").format(date);
}
Note: If you don’t want explicit the '01st' one d is enough.
May not be better...but shorter
static final _dayMap = {1: 'st', 2: 'nd', 3: 'rd'};
static String dayOfMonth(int day) => "$day${_dayMap[day] ?? 'th'}";