Persian date picker for Flutter
jalali_calendar_picker: a Material 3 Jalali date picker and range picker for Flutter with Saturday-first weeks, Persian digits and right-to-left layout.
Persian (Jalali, Shamsi) date picker and range picker for Flutter, built on jalali_date. انتخابگر تاریخ و بازهی تاریخ شمسی برای Flutter.
- Material 3, follows your app's
ColorScheme. - Saturday-first weeks, Fridays marked as the weekend.
- Persian digits by default, Latin digits on request.
- Right-to-left layout by default, even inside a left-to-right app.
- Day, month, and year views for quick jumps.
- Limits with
firstDate,lastDate, andselectableDayPredicate. - Persian labels; the dialog texts can be changed with
helpText,confirmText, andcancelText.
Installation
jalali_calendar_picker is published on pub.dev:
flutter pub add jalali_calendar_pickerjalali_calendar_picker re-exports jalali_date, so one import is enough:
import 'package:jalali_calendar_picker/jalali_calendar_picker.dart';Dialogs
final date = await showPersianDatePicker(
context: context,
initialDate: PersianDate.now(),
firstDate: PersianDate(1400, 1, 1),
lastDate: PersianDate(1410, 12, 29),
);
if (date != null) print(date.format('EEEE d MMMM yyyy')); // یکشنبه 1 مهر 1403
final range = await showPersianDateRangePicker(context: context);
if (range != null) print('${range.length} days');Both return null when the dialog is cancelled or dismissed. The range dialog returns a one-day range when only a start was picked.
| Parameter | Default |
|---|---|
initialDate / initialRange | today, clamped to the limits / none |
firstDate, lastDate | PersianDate.min, PersianDate.max |
selectableDayPredicate | every day |
persianDigits | true |
helpText | انتخاب تاریخ / انتخاب بازه |
confirmText, cancelText | تأیید, لغو |
textDirection | TextDirection.rtl |
Inline calendars
PersianCalendarDatePicker(
selectedDate: selected,
onDateChanged: (date) => setState(() => selected = date),
selectableDayPredicate: (day) => !day.isWeekend,
)
PersianCalendarRangePicker(
onRangeChanged: (range) => setState(() => this.range = range),
)For other selection rules, such as several separate days, use PersianCalendar directly with your own isSelected, isInRange, and onDayTapped.
Holidays
iranian_holidays gives Iran's official holidays, calculated offline on the device or fetched from an online source.
The offline source answers synchronously, so it fits selectableDayPredicate directly:
final holidays = OfflineHolidaySource();
PersianCalendarDatePicker(
selectedDate: selected,
onDateChanged: (date) => setState(() => selected = date),
selectableDayPredicate: holidays.isWorkingDay, // no Fridays or holidays
)With an online source, load a month with HolidaySource.month first, then pass a predicate over the result, or mark the days in your own PersianCalendar cells.
Building a date picker
For a ready-made Flutter date picker and range picker, use jalali_calendar_picker. This package has no widgets, but it has the calendar logic a picker of your own needs. A month grid with Saturday in the first column:
List<PersianDate?> monthCells(int year, int month) {
final first = PersianDate(year, month, 1);
return [
for (var i = 1; i < first.weekdayPersian; i++) null, // leading blanks
...first.daysUntil(first.lastDayOfMonth),
];
}
final header = [
for (var i = 0; i < 7; i++) PersianDate(1403, 1, 4).addDays(i).weekdayNameShort,
]; // ش ی د س چ پ ج, 1403/01/04 is a SaturdayOther building blocks:
- Navigation:
addMonths(1),addMonths(-1),addYears(1); the day is clamped, so moving from 1403/06/31 lands on 1403/07/30. - Selection limits:
PersianDate.min,PersianDate.max,isBefore,isAfter, or aPersianDateRangeandcontains. - Highlights:
isToday,isWeekend(Friday),isSameDayfor the selected day. - Range selection:
PersianDateRangewithoverlapsanddays. - Text input:
PersianDate.tryParseaccepts Persian digits from a Persian keyboard. - Labels:
monthName,weekdayNameShort,format('MMMM yyyy', persianDigits: true). - Right-to-left layout is the widget's job; in Flutter, wrap the grid in
Directionality(textDirection: TextDirection.rtl, ...).