Get current Week of the Month as a Number - flutter

How do I get the current week of the month as a number in Dart? I need to create some sort of calender with a week view where it says something like "2. Week of January"

You can use DateTime().now() to get the current time and date of the system or today's date also. Here is the code snippet below:
// Current date and time of system
String date = DateTime.now().toString();
// This will generate the time and date for first day of month
String firstDay = date.substring(0, 8) + '01' + date.substring(10);
// week day for the first day of the month
int weekDay = DateTime.parse(firstDay).weekday;
DateTime testDate = DateTime.now();
int weekOfMonth;
// If your calender starts from Monday
weekDay--;
weekOfMonth = ((testDate.day + weekDay) / 7).ceil();
print('Week of the month: $weekOfMonth');
weekDay++;
// If your calender starts from sunday
if (weekDay == 7) {
weekDay = 0;
}
weekOfMonth = ((testDate.day + weekDay) / 7).ceil();
print('Week of the month: $weekOfMonth');
Alternatively, if are looking for a complete implementation of the calender month UI then click here

My Answer is impaired from #dblank answer
extension DateTimeExtension on DateTime {
int get weekOfMonth {
var date = this;
final firstDayOfTheMonth = DateTime(date.year, date.month, 1);
int sum = firstDayOfTheMonth.weekday - 1 + date.day;
if (sum % 7 == 0) {
return sum ~/ 7;
} else {
return sum ~/ 7 + 1;
}
}
}
Then use it like this:
var wom = DateTime.now().weekOfMonth;

extension DateTimeExtension on DateTime {
int get weekOfMonth {
var wom = 0;
var date = this;
while (date.month == month) {
wom++;
date = date.subtract(const Duration(days: 7));
}
return wom;
}
}
Then use it like this:
var wom = DateTime.now().weekOfMonth;

Related

How can I add working days to a specific date (Flutter)?

I want to add the calulated working days to a specific date.
For example
I want to add 14 working days
date -> 08.17.2022 (it is input)
newDate -> 09.06.20222 (it is output)
I tried it with the code below but it didn't work as I want. What is my wrong? How can I do that?
Thanks in advance.
final workingDays = <DateTime>[];
final currentDate = DateTime.fromMicrosecondsSinceEpoch(
widget.siparisModel.siparisTarih.microsecondsSinceEpoch);
final orderDate = currentDate.add(Duration(days: 15));
DateTime indexDate = currentDate;
while (indexDate.difference(orderDate).inDays != 0) {
final isWeekendDay = indexDate.weekday == DateTime.saturday || indexDate.weekday == DateTime.sunday;
if (!isWeekendDay) {
workingDays.add(indexDate);
}
indexDate = indexDate.add(Duration(days: 15));
}
You could do something like this:
var newDate = DateTime(2022, 08, 17); // Copy from some "currentDate"
var numOfWeekdaysToAdd = 14;
while (numOfWeekdaysToAdd > 0) {
do {
newDate = newDate.add(Duration(days: 1));
} while (newDate.weekday == DateTime.saturday || newDate.weekday == DateTime.sunday);
numOfWeekdaysToAdd--;
}
Working DartPad demo:
https://dartpad.dev/?id=6ef6f4306944b350edfb77905239297e
If you want to, you could extend the "weekend-check" and make it more complex to also check for holidays in a specific locale. In that case I'd have a list of holiday-dates, and just add something like holidayDates.contains(newDate)

How to get the first, second, third, and fourth week of the month?

I want to get all four weeks (first and last day date) on the current month with Monday as the start of the week.
I can only figure out how to get the current week's first and last date with this code:
var firstDayOfTheWeek = DateTime.now().subtract(Duration(days: DateTime.now().weekday - 1));
var lastDayOfTheWeek = DateTime.now().add(Duration(days: DateTime.daysPerWeek - DateTime.now().weekday));
Thanks in advance!
Below method return next weekday's DateTime what you want from now or specific day.
DateTime getNextWeekDay(int weekDay, {DateTime from}) {
DateTime now = DateTime.now();
if (from != null) {
now = from;
}
int remainDays = weekDay - now.weekday + 7;
return now.add(Duration(days: remainDays));
}
The weekday parameter can be came like below DateTime const value or just int value.
class DateTime {
...
static const int monday = 1;
static const int tuesday = 2;
static const int wednesday = 3;
static const int thursday = 4;
static const int friday = 5;
static const int saturday = 6;
static const int sunday = 7;
...
}
If you want to get next Monday from now, call like below.
DateTime nextMonday = getNextWeekDay(DateTime.monday);
If you want to get next next Monday from now, call like below.
Or you just add 7 days to 'nextMonday' variable.
DateTime nextMonday = getNextWeekDay(DateTime.monday);
DateTime nextNextMonday = getNextWeekDay(DateTime.monday, from: nextMonday);
or
DateTime nextNextMonday = nextMonday.add(Duration(days: 7));

How to display time ago like Youtube in Flutter

I'm writing a flutter app to clone some Youtube functionalities using Youtube API V3.
The app fetches video timestamp as a String from youtube video API
Each timestamp has this format :
YYYY-MM-DDTHH:MM:SSZ
One example would be:
2020-07-12T20:42:19Z
I would like to display in a text :
1 hour
1 hours ago
4 weeks ago
11 months ago
1 year ago
...
I've created an extension on String
extension StringExtension on String {
static String displayTimeAgoFromTimestamp(String timestamp) {
final year = int.parse(timestamp.substring(0, 4));
final month = int.parse(timestamp.substring(5, 7));
final day = int.parse(timestamp.substring(8, 10));
final hour = int.parse(timestamp.substring(11, 13));
final minute = int.parse(timestamp.substring(14, 16));
final DateTime videoDate = DateTime(year, month, day, hour, minute);
final int diffInHours = DateTime.now().difference(videoDate).inHours;
String timeAgo = '';
String timeUnit = '';
int timeValue = 0;
if (diffInHours < 1) {
final diffInMinutes = DateTime.now().difference(videoDate).inMinutes;
timeValue = diffInMinutes;
timeUnit = 'minute';
} else if (diffInHours < 24) {
timeValue = diffInHours;
timeUnit = 'hour';
} else if (diffInHours >= 24 && diffInHours < 24 * 7) {
timeValue = (diffInHours / 24).floor();
timeUnit = 'day';
} else if (diffInHours >= 24 * 7 && diffInHours < 24 * 30) {
timeValue = (diffInHours / (24 * 7)).floor();
timeUnit = 'week';
} else if (diffInHours >= 24 * 30 && diffInHours < 24 * 12 * 30) {
timeValue = (diffInHours / (24 * 30)).floor();
timeUnit = 'month';
} else {
timeValue = (diffInHours / (24 * 365)).floor();
timeUnit = 'year';
}
timeAgo = timeValue.toString() + ' ' + timeUnit;
timeAgo += timeValue > 1 ? 's' : '';
return timeAgo + ' ago';
}
}
Then call in text:
StringExtension.displayTimeAgoFromTimestamp(video.timestamp)
You can use the timeago package
example code below
import 'package:timeago/timeago.dart' as timeago;
main() {
final fifteenAgo = new DateTime.now().subtract(new Duration(minutes: 15));
print(timeago.format(fifteenAgo)); // 15 minutes ago
print(timeago.format(fifteenAgo, locale: 'en_short')); // 15m
print(timeago.format(fifteenAgo, locale: 'es')); // hace 15 minutos
}
to use it with the YYYY-MM-DDTHH:MM:SSZ time format you can convert the String to a DateTime then perform the operation on the DateTime variable
DateTime time = DateTime.parse("2020-07-12T20:42:19Z");
print(timeago.format(time));
I've created reusable function for sample, this might be helpful!!
import 'package:intl/intl.dart';
//for DateTime manipulation need to add this package
import 'package:timeago/timeago.dart' as timeago;
void main(){
//creating this getTimeAgo function to format dateTime with user inputs
dynamic getTimeAgo(DateTime d) {
dynamic value = "";
//setting current time variable now
final now = DateTime.now();
//converting the user provided date to LocalTime
final recvDate = d.toLocal();
//declaring today's date in today variable
final today = DateTime(now.year, now.month, now.day);
//declaring yesterday's date in yesterday variable
final yesterday = DateTime(now.year, now.month, now.day - 1);
//declaring user provided date's in date variable
final date = DateTime(recvDate.year, recvDate.month, recvDate.day);
//comparing today's date is equal to user provided date then return value with timeAgo flutter package response
if (date == today) {
final curtimeNow = timeago.format(d);
if (curtimeNow == 'a day ago') {
value = "1 day ago";
} else if (curtimeNow == 'about an hour ago') {
value = "1 hour ago";
} else {
value = curtimeNow;
}
} //comparing yesterday's date is equal to user provided date then return 1 day ago
else if (date == yesterday) {
value='1 day ago';
} //else the user provided date then return as the date format of dd MMM yyyy Eg. 10 Mar 2022
else {
value = DateFormat('dd MMM yyyy').format(date);
}
//returning the response
return value;
}
//declaring the date which is to used be formatted
var recvdDateTime=DateTime.now().subtract(Duration(minutes: 45));;
//calling the getTimeAgo (fn) with user input
getTimeAgo(DateTime.parse(recvdDateTime));
}

Dart: How to find number of days between two dates excluding Weekend or Predicate

I need to calculate number of days between two dates in Dart.
There is built in function for that.
leaveEndDate.difference(leaveStartDate).inDays
But I do not want weekends to be included.
Is there any way I can traverse between these 2 Dates or I can just exclude weekends.
I think you have no other choice than looping through all the days to check if this is a weekend day or not :
void main() {
DateTime date1 = DateTime(2019, 12, 01);
DateTime date2 = DateTime(2019, 12, 31);
print(getDifferenceWithoutWeekends(date1, date2));
}
int getDifferenceWithoutWeekends(DateTime startDate, DateTime endDate) {
int nbDays = 0;
DateTime currentDay = startDate;
while (currentDay.isBefore(endDate)) {
currentDay = currentDay.add(Duration(days: 1));
if (currentDay.weekday != DateTime.saturday && currentDay.weekday != DateTime.sunday) {
nbDays += 1;
}
}
return nbDays;
}
Result :
22
EDIT :
Another solution, not sure it is faster but can be useful if you need to identify the dates (you could return list<DateTime> instead of List<int> to see which day is a weekend day).
Here I build each days between the 2 dates and return 1 if this is not a weekend day, then sum the list :
void main() {
DateTime startDate = DateTime(2019, 12, 01);
DateTime endDate = DateTime(2019, 12, 31);
int nbDays = endDate.difference(startDate).inDays + 1;
List<int> days = List.generate(nbDays, (index) {
int weekDay = DateTime(startDate.year, startDate.month, startDate.day + (index)).weekday;
if (weekDay != DateTime.saturday && weekDay != DateTime.sunday) {
return 1;
}
return 0;
});
print(days.reduce((a, b) => a + b));
}
I have also prepared a function which will traverse to all dates between two dates in Dart and will calculate number of days inBetween.
int calculateDaysBetween(DateTime mStartDate, DateTime mEndDate) {
int leaveDays = mEndDate.difference(mStartDate).inDays + 1;
int leaveBalance = 0;
var mTempDateTime =
DateTime(mStartDate.year, mStartDate.month, mStartDate.day);
for (int i = 0; i < leaveDays; i++) {
mTempDateTime = DateTime(
mTempDateTime.year, mTempDateTime.month, mTempDateTime.day + 1);
if (mTempDateTime.weekday == DateTime.friday ||
mTempDateTime.weekday == DateTime.saturday) {
print('is weekend');
} else {
leaveBalance++;
}
print(mTempDateTime);
}
// Total number of days between two dates excluding weekends.
return leaveBalance;
}
Improve #Developine Answer and make it more reusable , I make 2 function.
1.Calculate Total Days Of Month
2.Calculate TotalWeekDayOfMonth
Get Total Days Of Month
int totalDaysOfMonth(int month, int year) {
final result = (month < 12) ? DateTime(year, month + 1, 0) : DateTime(year + 1, 1, 0);
return result.day;
}
Get Total WeekDay Of Month
int totalWeekDayOfMonth(int year, int month, {int day = 1}) {
int totalDayOfMonth = totalDaysOfMonth(year, month);
int result = 0;
DateTime tempDateTime = DateTime(year, month, day);
for (int i = day; i <= totalDayOfMonth; i++) {
tempDateTime = DateTime(tempDateTime.year, tempDateTime.month, i);
if (tempDateTime.weekday == DateTime.saturday || tempDateTime.weekday == DateTime.sunday) {
print('is weekend');
} else {
result++;
}
}
return result;
}
How To Use It
void main(){
final resultWithoutDay = totalWeekDayOfMonth(2019,12);
final resultWithDay = totalWeekDayOfMonth(2019,12,day: 16);
print("Without Day $resultWithoutDay"); // 22
print("With Day $resultWithDay"); // 12
}

Add/Subtract months/years to date in dart?

I saw that in dart there is a class Duration but it cant be used add/subtract years or month. How did you managed this issue, I need to subtract 6 months from an date. Is there something like moment.js for dart or something around?
Thank you
Okay so you can do that in two steps, taken from #zoechi (a big contributor to Flutter):
Define the base time, let us say:
var date = new DateTime(2018, 1, 13);
Now, you want the new date:
var newDate = new DateTime(date.year, date.month - 1, date.day);
And you will get
2017-12-13
You can use the subtract and add methods
date1.subtract(Duration(days: 7, hours: 3, minutes: 43, seconds: 56));
date1.add(Duration(days: 1, hours: 23)));
Flutter Docs:
Subtract
Add
Try out this package, Jiffy. Adds and subtracts date time with respect to how many days there are in a month and also leap years. It follows the simple syntax of momentjs
You can add and subtract using the following units
years, months, weeks, days, hours, minutes, seconds and milliseconds
To add 6 months
DateTime d = Jiffy().add(months: 6).dateTime; // 2020-04-26 10:05:57.469367
// You can also add you own Datetime object
DateTime d = Jiffy(DateTime(2018, 1, 13)).add(months: 6).dateTime; // 2018-07-13 00:00:00.000
You can also do chaining using dart method cascading
var jiffy = Jiffy().add(months: 5, years: 1);
DateTime d = jiffy.dateTime; // 2021-03-26 10:07:10.316874
// you can also format with ease
String s = jiffy.format("yyyy, MMM"); // 2021, Mar
// or default formats
String s = jiffy.yMMMMEEEEdjm; // Friday, March 26, 2021 10:08 AM
You can use subtract and add methods
Subtract
Add
But you have to reassign the result to the variable, which means:
This wouldn't work
date1.add(Duration(days: 1, hours: 23)));
But this will:
date1 = date1.add(Duration(days: 1, hours: 23)));
For example:
void main() {
var d = DateTime.utc(2020, 05, 27, 0, 0, 0);
d.add(Duration(days: 1, hours: 23));
// the prev line has no effect on the value of d
print(d); // prints: 2020-05-27 00:00:00.000Z
//But
d = d.add(Duration(days: 1, hours: 23));
print(d); // prints: 2020-05-28 23:00:00.000Z
}
Dartpad link
In simple way without using any lib you can add Month and Year
var date = new DateTime(2021, 1, 29);
Adding Month :-
date = DateTime(date.year, date.month + 1, date.day);
Adding Year :-
date = DateTime(date.year + 1, date.month, date.day);
Not so simple.
final date = DateTime(2017, 1, 1);
final today = date.add(const Duration(days: 1451));
This results in 2020-12-21 23:00:00.000 because Dart considers daylight to calculate dates (so my 1451 days is missing 1 hour, and this is VERY dangerous (for example: Brazil abolished daylight savings in 2019, but if the app was written before that, the result will be forever wrong, same goes if the daylight savings is reintroduced in the future)).
To ignore the dayligh calculations, do this:
final date = DateTime(2017, 1, 1);
final today = DateTime(date.year, date.month, date.day + 1451);
Yep. Day is 1451 and this is OK. The today variable now shows the correct date and time: 2020-12-12 00:00:00.000.
It's pretty straightforward.
Simply add or subtract with numbers on DateTime parameters based on your requirements.
For example -
~ Here I had a requirement of getting the date-time exactly 16 years before today even with milliseconds and in the below way I got my solution.
DateTime today = DateTime.now();
debugPrint("Today's date is: $today"); //Today's date is: 2022-03-17 09:08:33.891843
After desired subtraction;
DateTime desiredDate = DateTime(
today.year - 16,
today.month,
today.day,
today.hour,
today.minute,
today.second,
today.millisecond,
today.microsecond,
);
debugPrint("16 years ago date is: $desiredDate"); // 16 years before date is: 2006-03-17 09:08:33.891843
Increase and Decrease of the day/month/year can be done by DateTime class
Initialise DateFormat which needed to be shown
var _inputFormat = DateFormat('EE, d MMM yyyy');
var _selectedDate = DateTime.now();
Increase Day/month/year:
_selectedDate = DateTime(_selectedDate.year,
_selectedDate.month + 1, _selectedDate.day);
Increase Day/month/year:
_selectedDate = DateTime(_selectedDate.year,
_selectedDate.month - 1, _selectedDate.day);
Above example is for only month, similar way we can increase or decrease year and day.
Can subtract any count of months.
DateTime subtractMonths(int count) {
var y = count ~/ 12;
var m = count - y * 12;
if (m > month) {
y += 1;
m = month - m;
}
return DateTime(year - y, month - m, day);
}
Also works
DateTime(date.year, date.month + (-120), date.day);
Future<void> main() async {
final DateTime now = DateTime.now();
var kdate = KDate.buildWith(now);
log("YEAR", kdate.year);
log("MONTH", kdate.month);
log("DATE", kdate.date);
log("Last Year", kdate.lastYear);
log("Last Month", kdate.lastMonth);
log("Yesturday", kdate.yesturday);
log("Last Week Date", kdate.lastWeekDate);
}
void log(title, data) {
print("\n$title ====> $data");
}
class KDate {
KDate({
this.now,
required this.year,
required this.month,
required this.date,
required this.lastYear,
required this.lastMonth,
required this.yesturday,
required this.lastWeekDate,
});
final DateTime? now;
final String? year;
final String? month;
final String? date;
final String? lastMonth;
final String? lastYear;
final String? yesturday;
final String? lastWeekDate;
factory KDate.buildWith(DateTime now) => KDate(
now: now,
year: (now.year).toString().split(" ")[0],
month: (now.month).toString().split(" ")[0],
date: (now.day).toString().split(" ")[0],
lastYear: (now.year - 1).toString().split(" ")[0],
lastMonth: DateTime(now.year, now.month, now.month)
.subtract(Duration(days: 28))
.toString()
.split(" ")[0]
.toString()
.split("-")[1],
yesturday: DateTime(now.year, now.month, now.day)
.subtract(Duration(days: 1))
.toString()
.split(" ")[0]
.toString()
.split("-")
.last,
lastWeekDate: DateTime(now.year, now.month, now.day)
.subtract(Duration(days: 7))
.toString()
.split(" ")[0]
.toString()
.split("-")
.last,
);
}
I'm a fan of using extensions in dart, and we can use them here like this:
extension DateHelpers on DateTime {
DateTime copyWith({
int? year,
int? month,
int? day,
int? hour,
int? second,
int? millisecond,
int? microsecond,
}) {
return DateTime(
year ?? this.year,
month ?? this.month,
day ?? this.day,
hour ?? this.hour,
second ?? this.second,
millisecond ?? this.millisecond,
microsecond ?? this.microsecond,
);
}
DateTime addYears(int years) {
return copyWith(year: this.year + years);
}
DateTime addMonths(int months) {
return copyWith(month: this.month + months);
}
DateTime addWeeks(int weeks) {
return copyWith(day: this.day + weeks*7);
}
DateTime addDays(int days) {
return copyWith(day: this.day + days);
}
}
You can then use this utility code as follows:
final now = DateTime.now();
final tomorrow = now.addDays(1);
final nextWeek = now.addWeeks(1);
final nextMonth = now.addMonths(1);
final nextYear = now.addYears(1);