Locale data doesn't load itself, so initialize it once in main:
await initializeDateFormatting();
Calling DateFormat with patterns all over the app gets messy. Collect the formats in one extension on DateTime? (copy-pasteable file at the bottom), where every case has a method, a null date becomes a placeholder instead of null on screen, and showing a date stays one call:
Add the weekday to the pattern when the user plans around it, like an appointment:
// Friday, 24 JulyString formattedWeekdayDate(String languageCode) { if (this == null) return 'N/A'; return DateFormat('EEEE, d MMMM', languageCode).format(this!);}
If everything on the screen happened today, show only the time:
// 14:44String get formattedTime { if (this == null) return 'N/A'; return DateFormat('HH:mm').format(this!);}
For recent dates, Today reads better than 24 July. Check today and yesterday first, then fall back to the date. Run the labels through your translations too:
// Today · Yesterday · 24 Jul 2016String formattedDayOrDate(String languageCode) { if (this == null) return 'N/A'; if (isToday) return 'Today'; if (isYesterday) return 'Yesterday'; return formattedDate(languageCode);}
The backend needs its own fixed format, never shown to users:
// 2016-07-24, for requests onlyString get formattedForBackend { if (this == null) return ''; return DateFormat('yyyy-MM-dd').format(this!);}
The whole file, ready to copy:
import 'package:intl/intl.dart';extension DateTimeX on DateTime? { // 24 July 2016, 14:44 String formattedDateTime(String languageCode) { if (this == null) return 'N/A'; return DateFormat('d MMMM yyyy, HH:mm', languageCode).format(this!); } // 24 Jul 2016 String formattedDate(String languageCode) { if (this == null) return 'N/A'; return DateFormat('d MMM yyyy', languageCode).format(this!); } // Friday, 24 July String formattedWeekdayDate(String languageCode) { if (this == null) return 'N/A'; return DateFormat('EEEE, d MMMM', languageCode).format(this!); } // 14:44 String get formattedTime { if (this == null) return 'N/A'; return DateFormat('HH:mm').format(this!); } // Today · Yesterday · 24 Jul 2016 String formattedDayOrDate(String languageCode) { if (this == null) return 'N/A'; if (isToday) return 'Today'; if (isYesterday) return 'Yesterday'; return formattedDate(languageCode); } // 2016-07-24, for requests only String get formattedForBackend { if (this == null) return ''; return DateFormat('yyyy-MM-dd').format(this!); } bool get isToday { if (this == null) return false; final DateTime now = DateTime.now(); return this!.year == now.year && this!.month == now.month && this!.day == now.day; } bool get isYesterday { if (this == null) return false; final DateTime yesterday = DateTime.now().subtract( const Duration(days: 1), ); return this!.year == yesterday.year && this!.month == yesterday.month && this!.day == yesterday.day; }}