DEV Community

Cover image for The Complete Flutter DateTime Toolkit You Didn't Know You Needed
Harsh Yadav
Harsh Yadav

Posted on

The Complete Flutter DateTime Toolkit You Didn't Know You Needed

The Problem Every Flutter Developer Faces

You're building a chat app. You need to show "2 hours ago" next to each message. Simple enough — you write a quick function:

dart
String getTimeAgo(DateTime date) {
final diff = DateTime.now().difference(date);
if (diff.inSeconds < 60) return '${diff.inSeconds} seconds ago';
if (diff.inMinutes < 60) return '${diff.inMinutes} minutes ago';
if (diff.inHours < 24) return '${diff.inHours} hours ago';
return '${diff.inDays} days ago';
}

Works great. Ship it.

Then your designer asks for "Yesterday" instead of "24 hours ago". Then your PM wants "Last week". Then a new requirement — the app needs Hindi support. Then you need a date range picker for the analytics dashboard. Then holiday-aware working day calculations for the HR module.

Before you know it, you have 3 packages in your pubspec and 200 lines of scattered utility code — duplicated across every project.

I've been there. That's exactly why I built smart_date_formatter.

What Is smart_date_formatter?

smart_date_formatter is a zero-dependency Flutter package that handles everything DateTime-related in one place.

yaml
dependencies:
smart_date_formatter: ^2.6.0

That's it. No intl. No timeago. No manual utility functions.

Feature 1 — Relative Time That Actually Makes Sense
dart
DateTime.now().subtract(Duration(seconds: 5)).timeAgo // "Just now"
DateTime.now().subtract(Duration(minutes: 25)).timeAgo // "25 minutes ago"
DateTime.now().subtract(Duration(days: 1)).timeAgo // "Yesterday"
DateTime.now().subtract(Duration(days: 9)).timeAgo // "Last week"
DateTime.now().add(Duration(days: 1)).timeAgo // "Tomorrow"
DateTime.now().add(Duration(days: 4)).timeAgo // "in 4 days"

Not just "24 hours ago" — actual human-readable strings that your users will understand.

Feature 2 — Custom Format Patterns

No more depending on intl just for date formatting:

dart
DateTime.now().format('dd-MM-yyyy') // "22-08-2026"
DateTime.now().format('EEE, dd MMM yyyy') // "Sat, 22 Aug 2026"
DateTime.now().format('hh:mm a') // "11:30 PM"
DateTime.now().toReadable // "Saturday, 22 August 2026"
DateTime.now().toISO // "2026-08-22T23:30:00"
Feature 3 — 16 Languages Out of the Box 🌍

This is where it gets interesting. Most date packages support English only. smart_date_formatter supports 16 languages — including 9 Indian languages:

dart
date.timeAgoIn(SdfLocale.hi) // "2 घंटे पहले" Hindi
date.timeAgoIn(SdfLocale.mr) // "2 तास पूर्वी" Marathi
date.timeAgoIn(SdfLocale.gu) // "2 કલાક પહેલાં" Gujarati
date.timeAgoIn(SdfLocale.bn) // "2 ঘন্টা আগে" Bengali
date.timeAgoIn(SdfLocale.ta) // "2 மணி நேரம் முன்பு" Tamil
date.timeAgoIn(SdfLocale.te) // "2 గంటలు క్రితం" Telugu
date.timeAgoIn(SdfLocale.kn) // "2 ಗಂಟೆಗಳ ಹಿಂದೆ" Kannada
date.timeAgoIn(SdfLocale.pa) // "2 ਘੰਟੇ ਪਹਿਲਾਂ" Punjabi
date.timeAgoIn(SdfLocale.de) // "2 Stunden her" German
date.timeAgoIn(SdfLocale.ja) // "2 時間前" Japanese
Feature 4 — Natural Language Parser 🔍

This one surprised even me when I built it. You can parse natural language strings into DateTime:

dart
SmartParser.parse("tomorrow") // DateTime
SmartParser.parse("next monday") // DateTime
SmartParser.parse("in 3 days") // DateTime
SmartParser.parse("first monday of month") // DateTime
SmartParser.parse("2 mondays ago") // DateTime
SmartParser.parse("end of this month") // DateTime
SmartParser.parse("q2") // DateTime (April)

// And in Indian languages!
SmartParser.parse("कल") // Hindi tomorrow
SmartParser.parse("उद्या") // Marathi tomorrow
SmartParser.parse("நாளை") // Tamil tomorrow
SmartParser.parse("আগামীকাল") // Bengali tomorrow
SmartParser.parse("આવતી કાલ") // Gujarati tomorrow
Feature 5 — Flutter Widgets
TimeAgoText — Auto Refreshing

dart
// No setState. No Timer. Just works.
TimeAgoText(
date: message.sentAt,
locale: SdfLocale.hi,
refreshRate: Duration(seconds: 30),
)
CountdownText — Live Countdown

dart
CountdownText(
target: saleEndsAt,
format: '{hh}:{mm}:{ss}',
finishedText: 'Sale Ended!',
onFinished: () => hideSaleBanner(),
)
SmartCalendar — Full Featured Calendar
dart
SmartCalendar(
events: myEvents,
initialView: CalendarView.month, // month/week/day/agenda
themeMode: ThemeMode.dark,
showWeekNumbers: true,
rangeSelectionMode: true,
markerStyle: EventMarkerStyle.both,
onDateSelected: (date, events) => print(date),
onRangeSelected: (start, end) => print('$start → $end'),
cellBuilder: (date, events, isSelected, isToday) {
// Fully custom cell UI
return MyCustomCell(date: date);
},
)
SmartDateField — Smart Date Input

dart
SmartDateField(
label: 'Due Date',
enableTimePicker: true,
enableNaturalLanguage: true, // type "next monday"!
showSuggestions: true,
validator: (date) {
if (date == null) return 'Required';
if (date.isPast) return 'Must be future date';
return null;
},
onChanged: (date) => setState(() => _dueDate = date),
)
SmartDateRangePicker — Visual Range Picker

dart
SmartDateRangePicker(
primaryColor: Colors.teal,
rangeHighlightColor: Colors.teal.withOpacity(0.15),
weekendColor: Colors.orange,
cellBorderRadius: 20,
presets: [
DateRangePreset.last7Days,
DateRangePreset.last30Days,
DateRangePreset.thisMonth,
],
onRangeSelected: (range) {
print('${range.start} → ${range.end}');
print('${range.days} days');
print(range.contains(DateTime.now())); // true
},
)

Feature 6 — Analytics Tools 📊
Streak Calculator
dart
// Perfect for habit trackers
StreakCalculator.currentStreak(dates) // 7
StreakCalculator.longestStreak(dates) // 21
StreakCalculator.isTodayCompleted(dates) // true
StreakCalculator.completionRate(
dates,
start: monthStart,
end: monthEnd,
) // 0.83
Date Grouper

dart
`DateGrouper.byMonth(activityDates)
// {'2026-06': [...], '2026-07': [...]}

DateGrouper.mostActiveWeekday(dates) // "Monday"
DateGrouper.mostActiveHour(dates) // 14
DateGrouper.averageGap(dates) // Duration(days: 2)
Feature 7 — Holiday-Aware Calculations 🎄
dart
final holidays = HolidayHelper.indianHolidays(2026);

// Is today a holiday?
DateTime.now().isHoliday(holidays: holidays)

// Add 5 working days, skipping holidays
date.addWorkingDaysWithHolidays(5, holidays: holidays)

// Working days between two dates
HolidayHelper.workingDaysBetween(
projectStart,
deadline,
holidays: holidays,
)`
Feature 8 — Date Range Helper 🗄️

Perfect for database queries and analytics filters:

dart
`final range = DateRangeHelper.thisMonth();

// SQLite
await db.query(
'orders',
where: 'created_at BETWEEN ? AND ?',
whereArgs: [
range.start.toIso8601String(),
range.end.toIso8601String(),
],
);

// Available ranges
DateRangeHelper.today()
DateRangeHelper.thisWeek()
DateRangeHelper.lastNDays(30)
DateRangeHelper.quarter(2)
DateRangeHelper.currentQuarter()`
Before vs After

Before:

yaml
dependencies:
timeago: ^3.6.0
intl: ^0.18.0

# + 200 lines of manual utility code
# + copy-pasted across every project

After:

yaml
dependencies:
smart_date_formatter: ^2.6.0

# done.
The Numbers
📦 Zero external dependencies
🌍 16 languages supported
🧪 300+ tests
⭐ 160/160 pub points (perfect score)
📱 All platforms: Android, iOS, Web, Windows, macOS, Linux
🔄 20+ versions released
Try It Live

Before adding it to your project, try every feature interactively:

👉 Live Playground

No installation. No setup. Just open and explore.

Get Started
bash
dart pub add smart_date_formatter
dart
import 'package:smart_date_formatter/smart_date_formatter.dart';

// That's it. Start using it.
DateTime.now().timeAgo // "Just now"
DateTime.now().calendar // "Today"
DateTime.now().toReadable // "Saturday, 22 August 2026"
Resources
📦 pub.dev: pub.dev
💻 GitHub: Github
🌐 Live Playground: Live
🐛 Issues: GitHub Issues

If this saved you time, please ⭐ the repo and 👍 like it on pub.dev — it helps other Flutter developers discover it.

— Harsh Yadav, Flutter Developer

Top comments (0)