Flutter - check if the current time is in between a given hourly range - flutter

I want to check if the current time is between my opening time and my closing time, knowing that the close time can some times be 2 am and the opening time is 3 am, for example, I have been trying to handle this problem logically for 2 weeks now and I can't wrap my head around it, this is my best try yet:
open = new DateTime(now.year, now.month, now.day, open.hour, open.minute);
close = new DateTime(now.year, now.month, now.day, close.hour, close.minute);
midnight = new DateTime(now.year, now.month, now.day, midnight.hour, midnight.minute);
if(close.hour > midnight.hour && close.hour < open.hour){
if(now.hour < midnight.hour){
DateTime theClose = new DateTime(now.year, now.month, now.day + 1, close.hour, close.minute);
if(now.isBefore(theClose) && now.isAfter(open)){
sendIt(context, notes);
}else{
_showToast("this branch is closed right now");
}
}else{
open = new DateTime(now.year, now.month, now.day - 1, open.hour, open.minute);
if(now.isBefore(close) && now.isAfter(open)){
sendIt(context, notes);
}else{
_showToast("this branch is closed right now");
}
}
}else{
if(now.isBefore(close) && now.isAfter(open)){
sendIt(context, notes);
}else{
_showToast("this branch is closed right now");
}
}

//checks if restaurant is open or closed
// returns true if current time is in between given timestamps
//openTime HH:MMAM or HH:MMPM same for closedTime
bool checkRestaurentStatus(String openTime, String closedTime) {
//NOTE: Time should be as given format only
//10:00PM
//10:00AM
// 01:60PM ->13:60
//Hrs:Min
//if AM then its ok but if PM then? 12+time (12+10=22)
TimeOfDay timeNow = TimeOfDay.now();
String openHr = openTime.substring(0, 2);
String openMin = openTime.substring(3, 5);
String openAmPm = openTime.substring(5);
TimeOfDay timeOpen;
if (openAmPm == "AM") {
//am case
if (openHr == "12") {
//if 12AM then time is 00
timeOpen = TimeOfDay(hour: 00, minute: int.parse(openMin));
} else {
timeOpen =
TimeOfDay(hour: int.parse(openHr), minute: int.parse(openMin));
}
} else {
//pm case
if (openHr == "12") {
//if 12PM means as it is
timeOpen =
TimeOfDay(hour: int.parse(openHr), minute: int.parse(openMin));
} else {
//add +12 to conv time to 24hr format
timeOpen =
TimeOfDay(hour: int.parse(openHr) + 12, minute: int.parse(openMin));
}
}
String closeHr = closedTime.substring(0, 2);
String closeMin = closedTime.substring(3, 5);
String closeAmPm = closedTime.substring(5);
TimeOfDay timeClose;
if (closeAmPm == "AM") {
//am case
if (closeHr == "12") {
timeClose = TimeOfDay(hour: 0, minute: int.parse(closeMin));
} else {
timeClose =
TimeOfDay(hour: int.parse(closeHr), minute: int.parse(closeMin));
}
} else {
//pm case
if (closeHr == "12") {
timeClose =
TimeOfDay(hour: int.parse(closeHr), minute: int.parse(closeMin));
} else {
timeClose = TimeOfDay(
hour: int.parse(closeHr) + 12, minute: int.parse(closeMin));
}
}
int nowInMinutes = timeNow.hour * 60 + timeNow.minute;
int openTimeInMinutes = timeOpen.hour * 60 + timeOpen.minute;
int closeTimeInMinutes = timeClose.hour * 60 + timeClose.minute;
//handling day change ie pm to am
if ((closeTimeInMinutes - openTimeInMinutes) < 0) {
closeTimeInMinutes = closeTimeInMinutes + 1440;
if (nowInMinutes >= 0 && nowInMinutes < openTimeInMinutes) {
nowInMinutes = nowInMinutes + 1440;
}
if (openTimeInMinutes < nowInMinutes &&
nowInMinutes < closeTimeInMinutes) {
return true;
}
} else if (openTimeInMinutes < nowInMinutes &&
nowInMinutes < closeTimeInMinutes) {
return true;
}
return false;
}

bool isValidTimeRange(TimeOfDay startTime, TimeOfDay endTime) {
TimeOfDay now = TimeOfDay.now();
return ((now.hour > startTime.hour) || (now.hour == startTime.hour && now.minute >= startTime.minute))
&& ((now.hour < endTime.hour) || (now.hour == endTime.hour && now.minute <= endTime.minute));
}

As you have noticed, using DateTime in our case is not the best solution because it relies on the month/year/day.
Instead, we can make use of the TimeOfDay class that does not rely on a specific day, but only on the time:
List<TimeOfDay> openingTimeRange = [TimeOfDay(hour: 2, minute: 30), TimeOfDay(hour: 15, minute: 45)]; // as an example
bool isOpen(List<TimeOfDay> openingTimeRange) {
TimeOfDay now = TimeOfDay.now();
return now.hour >= openingTimeRange[0].hour
&& now.minute >= openingTimeRange[0].minute
&& now.hour <= openingTimeRange[1].hour
&& now.minute <= openingTimeRange[1].minute;
}

I have a simple solution if your time format is in 24 hours. For that you don't require any external library.
bool _getStoreOpenStatus(String openTime, String closeTime) {
bool result = false;
DateTime now = DateTime.now();
int nowHour = now.hour;
int nowMin = now.minute;
print('Now: H$nowHour M$nowMin');
var openTimes = openTime.split(":");
int openHour = int.parse(openTimes[0]);
int openMin = int.parse(openTimes[1]);
print('OpenTimes: H$openHour M$openMin');
var closeTimes = closeTime.split(":");
int closeHour = int.parse(closeTimes[0]);
int closeMin = int.parse(closeTimes[1]);
print('CloseTimes: H$closeHour M$closeMin');
if(nowHour >= openHour && nowHour <= closeHour) {
if(nowMin > openMin && nowMin < closeMin) result = true;
}
return result;
}

If you use your time in the digital format [0..23] for hours, then you can convert the time to the amount of seconds that have past in that day. Do the same for the ranges you would like to check and see whether the current time past in seconds are between the two number ranges (in seconds):
TimeOfDay now = TimeOfDay.now(); // or DateTime object
TimeOfDay openingTime = TimeOfDay(hours: ??, minutes:??); // or leave as DateTime object
TimeOfDay closingTime = TimeOfDay(hours: ??, minutes:??); // or leave as DateTime object
int shopOpenTimeInSeconds = openingTime.hour * 60 + openingTime.minute;
int shopCloseTimeInSeconds = closingTime.hour * 60 + closingTime.minute;
int timeNowInSeconds = now.hour * 60 + now.minute;
if (shopOpenTimeInSeconds <= timeNowInSeconds &&
timeNowInSeconds <= shopCloseTimeInSeconds) {
// OPEN;
} else {
// CLOSED;
}

Related

how to get recent month data in listview in flutter

I am making an app where I need to fetch recent transactions,
Here I want to load all transaction of current month + other last two months Transactions
here I don't mean to calculate in days...like 60 days + current month days because its making complicated for testing leap year...
What I want is simple,
Today its 14th Jan 2023 so I want all data of Jan-23,Dec-22,Nov-22
here is my code for current month + previous month, but not happy with such basic code...need advance level code so that I can update based on Number of months requirement
List<TransactionModel> get showRecentTransactions {
int year=DateTime.now().year;
int month=DateTime.now().month;
if(month==1)
{
return _transactions.where((element) => element.date.year==DateTime.now().year && element.date.month==DateTime.now().month || element.date.month==12 && element.date.year==year-1).toList();
}
else
{
return _transactions.where((element) => element.date.year==DateTime.now().year && element.date.month==DateTime.now().month || element.date.month==month-1 && element.date.year==year).toList();
}
}
You can try this way:
List<String> get showRecentTransactions {
DateTime now = DateTime.now();
late DateTime lastMonth;
late DateTime secondLastMonth;
if (now.month == 2) {
lastMonth = DateTime(now.year, 1, 10);
secondLastMonth = DateTime(now.year - 1, 12, 10);
} else if (now.month == 1) {
lastMonth = DateTime(now.year - 1, 12, 10);
secondLastMonth = DateTime(now.year - 1, 11, 10);
} else {
lastMonth = DateTime(now.year, now.month - 1, 10);
secondLastMonth = DateTime(now.year, now.month - 2, 10);
}
return _transactions
.where((element) =>
(element.date.year == now.year &&
element.date.month == now.month) ||
(element.date.year == lastMonth.year &&
element.date.month == lastMonth.month) ||
(element.date.year == secondLastMonth.year &&
element.date.month == secondLastMonth.month))
.toList();
}

Compare two time in flutter

I would like to compare last_uploaded_time with current time.
How to check whether the two time is more or less than one minute?
bool compareTime(String starts) {
print(starts);
var start = starts.split(":");
DateTime currentDateTime = DateTime.now();
String currentTime =
DateFormat(DateUtil.TIME_FORMAT).format(currentDateTime);
print(currentTime);
var end = currentTime.split(":");
DateTime initDateTime = DateTime(
currentDateTime.year, currentDateTime.month, currentDateTime.day);
var startDate = (initDateTime.add(Duration(hours: int.parse(start[0]))))
.add(Duration(minutes: int.parse(start[1])));
var endDate = (initDateTime.add(Duration(hours: int.parse(end[0]))))
.add(Duration(minutes: int.parse(end[1])));
if (currentDateTime.isBefore(endDate) &&
currentDateTime.isAfter(startDate)) {
print("CURRENT datetime is between START and END datetime");
return true;
} else {
print("NOT BETWEEN");
return false;
}
}
Output
I/flutter (12908): 01:16
I/flutter (12908): 01:40
I/flutter (12908): NOT BETWEEN
difference
not exactly working with minutes and seconds so you can use some custom algorithm like
import 'package:intl/intl.dart';
class IntelModel { static String timeSinceDate(DateTime date) {
final now = DateTime.now();
final difference = now.toLocal().difference(date.toLocal());
if ((now.day - date.day) >= 8) {
return 'A few weeks ago';
} else if ((now.day - date.day) >= 1) {
return '${(now.day - date.day)} days ago';
} else if (now.day == date.day) {
if (now.hour > date.hour) {
if ((now.hour - date.hour) >= 2) {
if (now.minute == date.minute) {
return '${(now.hour - date.hour)} hours ago';
} else {
var mins = now.minute - date.minute;
if (mins > 1) {
return '${(now.hour - date.hour)} h ${(now.minute - date.minute)} minutes ago';
} else {
return '${(now.hour - date.hour) - 1} h ${60 + mins} minutes ago';
}
}
} else if ((now.hour - date.hour) == 1) {
int timeMin = now.minute + (60 - date.minute);
if (timeMin == 60) {
return '1 hours ago';
} else if (timeMin >= 60) {
return '1 h ${timeMin - 60} mins ago';
} else {
return '$timeMin minutes ago';
}
}
} else if (now.hour == date.hour) {
if (now.minute > date.minute) {
return '${(now.minute - date.minute)} minutes ago';
} else if (date.minute == now.minute) {
return '${(now.second - date.second)} seconds ago';
}
}
} else {
return 'Error in time';
} } }
void main() {
String getDifference(DateTime date){
Duration duration = DateTime.now().difference(date);
String differenceInMinutes = (duration.inMinutes).toString();
return differenceInMinutes;
}
String str = getDifference(DateTime.parse('2021-09-24'));
print (str);
}
i tried above code on dartpad, you can use this to compare tow dateTime variables. As per above example, you can get more options to compare for eg duration.inDays,duration.inHours,duration.inSeconds etc.

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));
}

How to determine which DateTime is greater or less than the other

How it should work:
Make sure that today is between 2020-April-01(timestampValidFrom - firebase timestamp format) and 2020-April-05(timestampValidTo).
I need like this query.
1)
timestampValidFrom <= today >= timestampValidTo
or
2)
.where('timestampValidFrom', isGreaterThanOrEqualTo: Timestamp.now())
.where('timestampValidTo', isLessThanOrEqualTo: Timestamp.now())
I have tried to fix this solution, but it does not work.
DateTime now = DateTime.now();
DateTime yesterday,tomorrow;
yesterday = DateTime(now.year, now.month, now.day); // today 12.00.00
tomorrow = DateTime(now.year, now.month, now.day +1); //tomorrow 12.00.00
if(yesterday.isAfter(snapshot.data[index].timestampValidFrom.toDate())
|| snapshot.data[index].timestampValidFrom.toDate().isBefore(tomorrow)
&& yesterday.isBefore(snapshot.data[index].timestampValidTo.toDate())
|| snapshot.data[index].timestampValidTo.toDate().isAfter(tomorrow)) {
// show widget
} else {
//emplty widget
}
you can use DateTime.compareTo to perform greater-than-or-equal-to or less-than-or-equal-to checks:
var today = DateTime.now();
var isValid = today.compareTo(timestampValidFrom) >= 0 &&
today.compareTo(timeStampValidTo) <= 0;
You can define operator <= and operator >= on DateTime as extensions to make this comparison easier to read. package:basics does this for you:
import 'package:basics/basics.dart';
...
var today = DateTime.now();
var isValid = today >= timestampValidFrom && today <= timestampValidTo;
Use the difference method.
final yesterday = DateTime(now.year, now.month, now.day); // today 12.00.00
final tomorrow = DateTime(now.year, now.month, now.day +1); //tomorrow 12.00.00
int diffInDays = tomorrow.difference(yesterday).inDays;
if (diffInDays == 0){
//custom code
print( "same day");
} else if( diffInDays > 0 ) {
// custom code
print("tomorrow is greater ");
} else{
// custom code
print(" yesterday is less" );
}
Hope it helps!
You can simply check whether the current date is between the promotion start date and end date, if yes show the promotion else hide it.
DateTime now = DateTime.now();
DateTime beg = snapshot.data[index].timestampValidFrom.toDate();
DateTime end = snapshot.data[index].timestampValidTo.toDate();
if(now.isAfter(beg) && now.isBefore(end)){
print('show promo');
} else{
print('remove promo');
}
It won't include the start & end date. For including the start date, check the following if statement:
if((now.difference(beg).inMinutes >= 0 || now.isAfter(beg)) && (now.isBefore(end) || now.difference(end).inMinutes <= 0)){
print('show promo');
}else{
print('remove promo');
}

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
}