CalendarDelegate<T extends DateTime> class abstract

Controls the calendar system used in the date picker.

A CalendarDelegate defines how dates are interpreted, formatted, and navigated within the picker. Different calendar systems (e.g., Gregorian, Nepali, Hijri, Buddhist) can be supported by providing custom implementations.

This example demonstrates how a CalendarDelegate is used to implement a custom calendar system in the date picker.

To see it in action, copy and run this code snippet on DartPad.

import 'package:material_ui/material_ui.dart';

/// Flutter code sample demonstrating how to use a custom [CalendarDelegate]
/// with [CalendarDatePicker] to implement a hypothetical calendar system
/// where even-numbered months have 21 days, odd-numbered months have 28 days,
/// and every month starts on a Monday.

void main() => runApp(const CalendarDatePickerApp());

class CalendarDatePickerApp extends StatelessWidget {
  const CalendarDatePickerApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: CalendarDatePickerExample());
  }
}

class CalendarDatePickerExample extends StatefulWidget {
  const CalendarDatePickerExample({super.key});

  @override
  State<CalendarDatePickerExample> createState() =>
      _CalendarDatePickerExampleState();
}

class _CalendarDatePickerExampleState extends State<CalendarDatePickerExample> {
  DateTime? selectedDate;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Custom Calendar')),
      body: Column(
        spacing: 16,
        children: <Widget>[
          CalendarDatePicker(
            initialDate: DateTime(2025, 2, 8),
            firstDate: DateTime(2025),
            lastDate: DateTime(2026),
            onDateChanged: (DateTime pickedDate) {
              setState(() {
                selectedDate = pickedDate;
              });
            },
            calendarDelegate: const CustomCalendarDelegate(),
          ),
          const Divider(height: 1),
          Text(
            selectedDate != null
                ? '${selectedDate!.day}/${selectedDate!.month}/${selectedDate!.year}'
                : 'No date selected',
          ),
        ],
      ),
    );
  }
}

/// A custom calendar system where even-numbered months have 21 days,
/// odd-numbered months have 28 days, and every month starts on a Monday.
///
/// This hypothetical calendar follows a fixed structure:
/// - **Even-numbered months (2, 4, 6, etc.)** always have **21 days**.
/// - **Odd-numbered months (1, 3, 5, etc.)** always have **28 days**.
/// - **The first day of every month is always a Monday**, ensuring a consistent weekly alignment.
class CustomCalendarDelegate extends CalendarDelegate<DateTime> {
  const CustomCalendarDelegate();

  @override
  int getDaysInMonth(int year, int month) {
    return month.isEven ? 21 : 28;
  }

  @override
  int firstDayOffset(int year, int month, MaterialLocalizations localizations) {
    return 1;
  }

  // ------------------------------------------------------------------------
  // All the implementations below are based on the Gregorian calendar system.

  @override
  DateTime now() => DateTime.now();

  @override
  DateTime dateOnly(DateTime date) => DateUtils.dateOnly(date);

  @override
  int monthDelta(DateTime startDate, DateTime endDate) =>
      DateUtils.monthDelta(startDate, endDate);

  @override
  DateTime addMonthsToMonthDate(DateTime monthDate, int monthsToAdd) {
    return DateUtils.addMonthsToMonthDate(monthDate, monthsToAdd);
  }

  @override
  DateTime addDaysToDate(DateTime date, int days) =>
      DateUtils.addDaysToDate(date, days);

  @override
  DateTime getMonth(int year, int month) => DateTime(year, month);

  @override
  DateTime getDay(int year, int month, int day) => DateTime(year, month, day);

  @override
  String formatMonthYear(DateTime date, MaterialLocalizations localizations) {
    return localizations.formatMonthYear(date);
  }

  @override
  String formatMediumDate(DateTime date, MaterialLocalizations localizations) {
    return localizations.formatMediumDate(date);
  }

  @override
  String formatShortMonthDay(
    DateTime date,
    MaterialLocalizations localizations,
  ) {
    return localizations.formatShortMonthDay(date);
  }

  @override
  String formatShortDate(DateTime date, MaterialLocalizations localizations) {
    return localizations.formatShortDate(date);
  }

  @override
  String formatFullDate(DateTime date, MaterialLocalizations localizations) {
    return localizations.formatFullDate(date);
  }

  @override
  String formatCompactDate(DateTime date, MaterialLocalizations localizations) {
    return localizations.formatCompactDate(date);
  }

  @override
  DateTime? parseCompactDate(
    String? inputString,
    MaterialLocalizations localizations,
  ) {
    return localizations.parseCompactDate(inputString);
  }

  @override
  String dateHelpText(MaterialLocalizations localizations) {
    return localizations.dateHelpText;
  }
}

See also:

Constructors

CalendarDelegate()
Creates a calendar delegate.
const

Properties

hashCode int
The hash code for this object.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

addDaysToDate(T date, int days) → T
Returns a DateTime with the added number of days and time set to midnight.
addMonthsToMonthDate(T monthDate, int monthsToAdd) → T
Returns a DateTime that is monthDate with the added number of months and the day set to 1 and time set to midnight.
dateHelpText(MaterialLocalizations localizations) String
The help text used on an empty InputDatePickerFormField to indicate to the user the date format being asked for.
dateOnly(T date) → T
Returns a DateTime with the date of the original, but time set to midnight.
datesOnly(DateTimeRange<T> range) DateTimeRange<T>
Returns a DateTimeRange with the dates of the original, but with times set to midnight.
firstDayOffset(int year, int month, MaterialLocalizations localizations) int
Computes the offset from the first day of the week that the first day of the month falls on.
formatCompactDate(T date, MaterialLocalizations localizations) String
Formats the date in a compact format.
formatFullDate(T date, MaterialLocalizations localizations) String
Formats day of week, month, day of month and year in a long-width format.
formatMediumDate(T date, MaterialLocalizations localizations) String
Formats the date using a medium-width format.
formatMonthYear(T date, MaterialLocalizations localizations) String
Formats the month and the year of the given date.
formatShortDate(T date, MaterialLocalizations localizations) String
Formats the date using a short-width format.
formatShortMonthDay(T date, MaterialLocalizations localizations) String
Formats the month and day of the given date.
formatYear(int year, MaterialLocalizations localizations) String
Full unabbreviated year format, e.g. 2017 rather than 17.
getDay(int year, int month, int day) → T
Returns a DateTime with the given year, month, and day.
getDaysInMonth(int year, int month) int
Returns the number of days in a month, according to the calendar system.
getMonth(int year, int month) → T
Returns a DateTime with the given year and month.
isSameDay(T? dateA, T? dateB) bool
Returns true if the two DateTime objects have the same day, month, and year, or are both null.
isSameMonth(T? dateA, T? dateB) bool
Returns true if the two DateTime objects have the same month and year, or are both null.
monthDelta(T startDate, T endDate) int
Determines the number of months between two DateTime objects.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
now() → T
Returns a DateTime representing the current date and time.
parseCompactDate(String? inputString, MaterialLocalizations localizations) → T?
Converts the given compact date formatted string into a DateTime.
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited