Manually writing the Arabic date in the datePicker is not working

When I switch showDatePicker to input mode (initialEntryMode: DatePickerEntryMode.input) using an Arabic locale, typing dates with Eastern-Arabic digits (e.g. ٢٠٢٠/١١/١١) doesn’t work. The field rejects every character and displays an error message in Arabic:

Which roughly translates to “Invalid date format.”

final picked = await showDatePicker(

context: context,

locale: const Locale('ar'),

initialEntryMode: DatePickerEntryMode.input,

firstDate: DateTime(2000),

lastDate: DateTime(2100),

initialDate: DateTime.now(),

);

example of my input: ٢٠٢٠/١١/١١

You might wanna consider filing an issue on Flutter’s github

You can try:

  1. Input formatter
  static const Map<String, String> _arabicToWesternDigits = {
    '٠': '0',
    '١': '1',
    '٢': '2',
    '٣': '3',
    '٤': '4',
    '٥': '5',
    '٦': '6',
    '٧': '7',
    '٨': '8',
    '٩': '9',
  };

Flutter’s date picker input validation doesn’t automatically convert Eastern-Arabic numerals to Western-Arabic numerals that the parsing logic expects.

showDatePicker doesn’t have 1. Input formatter or on change !

Try this code:

import 'package:flutter/services.dart';
class ArabicDigitsInputFormatter extends TextInputFormatter {
  static const Map<String, String> _arabicToWesternDigits = {
    '٠': '0',
    '١': '1',
    '٢': '2',
    '٣': '3',
    '٤': '4',
    '٥': '5',
    '٦': '6',
    '٧': '7',
    '٨': '8',
    '٩': '9',
  };
  @override
  TextEditingValue formatEditUpdate(
    TextEditingValue oldValue,
    TextEditingValue newValue,
  ) {
    String convertedText = newValue.text;

    // Convert Eastern-Arabic digits to Western-Arabic digits
    _arabicToWesternDigits.forEach((arabic, western) {
      convertedText = convertedText.replaceAll(arabic, western);
    });
    return TextEditingValue(
      text: convertedText,
      selection: TextSelection.collapsed(offset: convertedText.length),
    );
  }
}
// Usage example with a custom TextField for date input
class ArabicDateInputField extends StatefulWidget {
  final Function(DateTime?) onDateSelected;

  const ArabicDateInputField({Key? key, required this.onDateSelected}) : super(key: key);
  @override
  State<ArabicDateInputField> createState() => _ArabicDateInputFieldState();
}
class _ArabicDateInputFieldState extends State<ArabicDateInputField> {
  final TextEditingController _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: _controller,
      inputFormatters: [
        ArabicDigitsInputFormatter(),
        // Add other formatters as needed
      ],
      decoration: InputDecoration(
        labelText: 'التاريخ',
        hintText: 'yyyy/mm/dd',
        suffixIcon: IconButton(
          icon: Icon(Icons.calendar_today),
          onPressed: () async {
            final picked = await showDatePicker(
              context: context,
              locale: const Locale('ar'),
              initialEntryMode: DatePickerEntryMode.input,
              firstDate: DateTime(2000),
              lastDate: DateTime(2100),
              initialDate: DateTime.now(),
            );
            if (picked != null) {
              _controller.text = '${picked.year}/${picked.month.toString().padLeft(2, '0')}/${picked.day.toString().padLeft(2, '0')}';
              widget.onDateSelected(picked);
            }
          },
        ),
      ),
      onSubmitted: (value) {
        try {
          final parts = value.split('/');
          if (parts.length == 3) {
            final date = DateTime(
              int.parse(parts[0]),
              int.parse(parts[1]),
              int.parse(parts[2]),
            );
            widget.onDateSelected(date);
          }
        } catch (e) {
          // Handle parsing error
        }
      },
    );
  }
}