Reputation: 2121
The question is how to format a Dart DateTime as a string stating the time elapsed similar to the way you see times displayed on Stack Overflow.
Is there any better method than this
String timeAgo(DateTime d) {
Duration diff = DateTime.now().difference(d);
if (diff.inDays > 365)
return "${(diff.inDays / 365).floor()} ${(diff.inDays / 365).floor() == 1 ? "year" : "years"} ago";
if (diff.inDays > 30)
return "${(diff.inDays / 30).floor()} ${(diff.inDays / 30).floor() == 1 ? "month" : "months"} ago";
if (diff.inDays > 7)
return "${(diff.inDays / 7).floor()} ${(diff.inDays / 7).floor() == 1 ? "week" : "weeks"} ago";
if (diff.inDays > 0)
return "${diff.inDays} ${diff.inDays == 1 ? "day" : "days"} ago";
if (diff.inHours > 0)
return "${diff.inHours} ${diff.inHours == 1 ? "hour" : "hours"} ago";
if (diff.inMinutes > 0)
return "${diff.inMinutes} ${diff.inMinutes == 1 ? "minute" : "minutes"} ago";
return "just now";
}
Thank you and hope it helps others
Upvotes: 46
Views: 41905
Reputation: 293
Text(
Jiffy.parse(jiffyDateTime.toString()).fromNow(),
style: TextStyle(color: BrandColors.grey, fontSize: 12)
)
No need to parse date&time format even in the list, make sure your pattern will follow this 'yyyy-MM-dd'
Upvotes: 0
Reputation: 3405
You can also try this package i created, Jiffy.
You can get relative time from now
// This returns time ago from now
Jiffy.now().fromNow(); // a few seconds ago
//You can also pass in a DateTime Object or a string or a list
Jiffy.parseFromDateTime(DateTime.now()).fromNow; // a few seconds ago
//or
Jiffy.parseFromDateTime(DateTime(2018, 10, 25)).fromNow(); // a year ago
Jiffy.parse("2020-10-25").fromNow(); // in a year
Manipulating is also simple in Jiffy
var dateTime = Jiffy.now().add(hours: 3, months: 2);
dateTime.fromNow(); // in 2 months
You can also get relative time from a specified time apart from now
Jiffy.parseFromList([2022, 10, 25])
.from(Jiffy.parseFromList([2022, 1, 25])); // in 10 months
Upvotes: 18
Reputation: 11
String timeAgoCustom(DateTime d) { // <-- Custom method Time Show (Display Example ==> 'Today 7:00 PM') // WhatsApp Time Show Status Shimila
Duration diff = DateTime.now().difference(d);
if (diff.inDays > 365)
return "${(diff.inDays / 365).floor()} ${(diff.inDays / 365).floor() == 1 ? "year" : "years"} ago";
if (diff.inDays > 30)
return "${(diff.inDays / 30).floor()} ${(diff.inDays / 30).floor() == 1 ? "month" : "months"} ago";
if (diff.inDays > 7)
return "${(diff.inDays / 7).floor()} ${(diff.inDays / 7).floor() == 1 ? "week" : "weeks"} ago";
if (diff.inDays > 0)
return "${DateFormat.E().add_jm().format(d)}";
if (diff.inHours > 0)
return "Today ${DateFormat('jm').format(d)}";
if (diff.inMinutes > 0)
return "${diff.inMinutes} ${diff.inMinutes == 1 ? "minute" : "minutes"} ago";
return "just now";
}
Add This Package --> intl: ^0.17.0
Time Show Example (Today 8:29 PM)
Upvotes: 1
Reputation: 53600
If you just want to use Datetime
library this is the way you can do it.
void main() {
final currentTime = DateTime.now();
print('Current time: $currentTime');
final threeWeeksAgo = currentTime.subtract(const Duration(days: 21));
print('Three weeks ago: $threeWeeksAgo');
}
This is what you get:
Current time: 2022-09-29 11:26:58.350
Three weeks ago: 2022-09-08 11:26:58.350
Upvotes: 0
Reputation: 12073
A variation on @Alex289's answer
extension DateHelpers on DateTime {
String toTimeAgoLabel({bool isIntervalNumericVisible = true}) {
final now = DateTime.now();
final durationSinceNow = now.difference(this);
final inDays = durationSinceNow.inDays;
if (inDays >= 1) {
return (inDays / 7).floor() >= 1
? isIntervalNumericVisible ? '1 week ago' : 'Last week'
: inDays >= 2
? '$inDays days ago'
: isIntervalNumericVisible
? '1 day ago'
: 'Yesterday';
}
final inHours = durationSinceNow.inHours;
if (inHours >= 1) {
return inHours >= 2
? '$inHours hours ago'
: isIntervalNumericVisible
? '1 hour ago'
: 'An hour ago';
}
final inMinutes = durationSinceNow.inMinutes;
if (inMinutes >= 2) {
return inMinutes >= 2
? '$inMinutes minutes ago'
: isIntervalNumericVisible
? '1 minute ago'
: 'A minute ago';
}
final inSeconds = durationSinceNow.inSeconds;
return inSeconds >= 3 ? '$inSeconds seconds ago' : 'Just now';
}
}
Upvotes: -1
Reputation: 685
Hope you got the answer! you just need to past your timestamp value in this method and you get a time ago formatted string.
String getVerboseDateTimeRepresentation(DateTime dateTime) {
DateTime now = DateTime.now().toLocal();
DateTime localDateTime = dateTime.toLocal();
if (localDateTime.difference(now).inDays == 0) {
var differenceInHours = localDateTime.difference(now).inHours.abs();
var differenceInMins = localDateTime.difference(now).inMinutes.abs();
if (differenceInHours > 0) {
return '$differenceInHours hours ago';
} else if (differenceInMins > 2) {
return '$differenceInMins mins ago';
} else {
return 'Just now';
}
}
String roughTimeString = DateFormat('jm').format(dateTime);
if (localDateTime.day == now.day &&
localDateTime.month == now.month &&
localDateTime.year == now.year) {
return roughTimeString;
}
DateTime yesterday = now.subtract(const Duration(days: 1));
if (localDateTime.day == yesterday.day &&
localDateTime.month == now.month &&
localDateTime.year == now.year) {
return 'Yesterday';
}
if (now.difference(localDateTime).inDays < 4) {
String weekday = DateFormat(
'EEEE',
).format(localDateTime);
return '$weekday, $roughTimeString';
}
return '${DateFormat('yMd').format(dateTime)}, $roughTimeString';
}
Upvotes: 0
Reputation: 2942
You can use this Method which will give you times ago.
String convertToAgo(String dateTime) {
DateTime input =
DateFormat('yyyy-MM-DDTHH:mm:ss.SSSSSSZ').parse(dateTime, true);
Duration diff = DateTime.now().difference(input);
if (diff.inDays >= 1) {
return '${diff.inDays} day${diff.inDays == 1 ? '' : 's'} ago';
} else if (diff.inHours >= 1) {
return '${diff.inHours} hour${diff.inHours == 1 ? '' : 's'} ago';
} else if (diff.inMinutes >= 1) {
return '${diff.inMinutes} minute${diff.inMinutes == 1 ? '' : 's'} ago';
} else if (diff.inSeconds >= 1) {
return '${diff.inSeconds} second${diff.inSeconds == 1 ? '' : 's'} ago';
} else {
return 'just now';
}
}
Upvotes: 0
Reputation: 13843
I simplify Paresh's answer by using DateTime extension
create a new dart file called date_time_extension.dart
and then write code like this
extension DateTimeExtension on DateTime {
String timeAgo({bool numericDates = true}) {
final date2 = DateTime.now();
final difference = date2.difference(this);
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';
}
}
}
and then, use it like this
import 'package:utilities/extensions/date_time_extension.dart'; // <--- import the file you just create
product.createdAt.timeAgo(numericDates: false) // use it on your DateTime property
Upvotes: 14
Reputation: 572
I used timeago for the exact purpose and found it quite useful. It has multiple format and different languages support as well.
Upvotes: 51