How to display time ago like Youtube in Flutter - 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));
}

Related

Show time difference between 2 date

I'm trying to show time difference between 2 date in my flutter app. How can I do so with my formatted date ? And I also need to show it as a string.
For example:
6 Jun 2022
14 Jun 2022 (8 Days)
Here's my current code:
Text(
'Created: ' +
DateFormat('d MMM y').format(
DateTime.parse(
ticketData['date_created']
.toDate()
.toString(),
),
),
style: primaryColor400Style.copyWith(
fontSize: fontSize13,
),
),
TextSpan(
text: DateFormat('d MMM y').format(
DateTime.parse(
ticketData['due_date']
.toDate()
.toString(),
),
),
style: weight400Style.copyWith(
fontSize: fontSize14,
color: hintColor,
),
),
You could utilize the difference() method from the DateTime class. Here some example:
void main() {
final String createdDateInput = '2022-06-03T01:37:02+0000';
final String dueDateInput = '2022-06-10T01:37:02+0000';
final DateTime createdDateTime = DateTime.parse(createdDateInput);
final DateTime dueDateTime = DateTime.parse (dueDateInput);
final String createdDate = DateFormat('d MMM y').format(createdDateTime);
final String dueDate = DateFormat('d MMM y').format(dueDateTime);
final Duration duration = dueDateTime.difference(createdDateTime);
print('$createdDate - $dueDate (${duration.inDays} day(s))');
}
Try this:
static String timeAgoSinceDate(String dateString,
{bool numericDates = true}) {
try {
DateTime notificationDate = DateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.parse(dateString, true)
.toUtc()
.toLocal();
final date2 = DateTime.now();
final difference = date2.difference(notificationDate);
if (difference.inDays > 8) {
return '${notificationDate.year}/${notificationDate.month}/${notificationDate.day}';
} else if ((difference.inDays / 7).floor() >= 1) {
return (numericDates) ? '1 week ago' : 'Last week';
} else if (difference.inDays >= 2) {
return '${difference.inDays} days ago';
} else if (difference.inDays >= 1) {
return (numericDates) ? '1 day ago' : 'Yesterday';
} else if (difference.inHours >= 2) {
return '${difference.inHours} hours ago';
} else if (difference.inHours >= 1) {
return (numericDates) ? '1 hour ago' : 'An hour ago';
} else if (difference.inMinutes >= 2) {
return '${difference.inMinutes} minutes ago';
} else if (difference.inMinutes >= 1) {
return (numericDates) ? '1 minute ago' : 'A minute ago';
} else if (difference.inSeconds >= 3) {
return '${difference.inSeconds} seconds ago';
} else {
return 'Just now';
}
} catch (e) {
return '';
}
}
You can also try this,
final birthdayDate = DateTime(1967, 10, 12);
final toDayDate = DateTime.now();
var different = toDayDate.difference(birthdayDate).inDays;
print(different);
The difference is measured in seconds and fractions of seconds. The difference above counts the number of fractional seconds between midnight at the beginning of those dates. If the dates above had been in local time, not UTC, then the difference between two midnights may not be a multiple of 24 hours due to daylight saving differences.
here is another way:
final DateTime startDate = DateTime.parse('2020-11-11');
final DateTime endDate = DateTime.parse('2022-11-11');
final int startDateInMS = startDate.millisecondsSinceEpoch;
final int endDateInMS = endDate.millisecondsSinceEpoch;
final Duration duration = Duration(milliseconds: endDateInMS - startDateInMS);
print('days: ${duration.inDays}');
print('Hours: ${duration.inHours}');
print('Minuts: ${duration.inMinutes}');
print('Seconds: ${duration.inSeconds}');

flutter:: Is it possible to change the timezone of a datetime?

I want to represent the time the file was saved as a string. The time in my country is 9 hours ahead of utc time. How can I change the current utc time to 9 hours faster?
String _getTime({required String filePath}) {
String fromPath = filePath.substring(
filePath.lastIndexOf('/') + 1, filePath.lastIndexOf('.'));
if (fromPath.startsWith("1", 0)) {
DateTime dateTime =
DateTime.fromMillisecondsSinceEpoch(int.parse(fromPath));
var dateLocal = dateTime.toLocal();
print(dateLocal);
print(dateTime);
int year = dateLocal.year;
int month = dateLocal.month;
int day = dateLocal.day;
int hour = dateLocal.hour;
int min = dateLocal.minute;
String dato = '$year-$month-$day--$hour:$min';
return dato;
} else {
return "No Date";
}
}
Use this package ---->>>>> https://pub.dev/packages/flutter_native_timezone
Add the package dependencies to your project, import the package into the file you're working in and write the code below to get your currenTimeZone
final String currentTimeZone = await FlutterNativeTimezone.getLocalTimezone();
debugPrint(currentTimeZone);

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

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

Get current Week of the Month as a Number

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;

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
}