Skip to content

Arabic ('ar') dates lost Arabic-Indic digits: ZERODIGIT removed from DateSymbols in 3.44 date localization update #187767

Closed

Description

@ziyad-aljohani

Steps to reproduce

  1. Create a Flutter app using flutter_localizations with Arabic (ar) in supportedLocales (e.g. via GlobalMaterialLocalizations.delegate).
  2. Run the app with the locale set to ar (or any Arabic regional locale such as ar_SA, which falls back to ar since only ar is registered).
  3. Format any date/time with intl, e.g. DateFormat.jm('ar').format(DateTime.now()).

Expected results

Digits are rendered using Arabic-Indic (Eastern Arabic) numerals, as they were up to and including Flutter 3.38:

٨:٣٠ م

Per CLDR, the default numbering system for the generic ar locale is arab (Arabic-Indic digits); only specific regional variants like ar_DZ, ar_MA, ar_TN default to latn.

Actual results

Since Flutter 3.44 (first appeared in 3.43.0-0.1.pre), digits are rendered as ASCII/Latin while day and month names remain Arabic:

8:30 م

Root cause

#181685 (reverted, then relanded in #182189, commit 3ea16190995) regenerated packages/flutter_localizations/lib/src/l10n/generated_date_localizations.dart and removed ZERODIGIT: '٠' from the 'ar' DateSymbols entry — it is the only ZERODIGIT removal in that diff:

git diff 1c1ba3a8390^ 1c1ba3a8390 -- packages/flutter_localizations/lib/src/l10n/generated_date_localizations.dart | grep "ZERODIGIT"
-    ZERODIGIT: '٠',

When ZERODIGIT is absent, intl's DateFormat silently falls back to ASCII '0' (localeZero => dateSymbols.ZERODIGIT ?? '0'), so every date formatted under the ar locale switches to Latin digits.

Because GlobalMaterialLocalizations.delegate injects the Flutter-bundled DateSymbols into intl via initializeDateFormattingCustom (overriding intl's own locale data), every app using flutter_localizations with Arabic is affected — including all DateFormat usages outside Flutter widgets, and packages like easy_localization.

Note the same ZERODIGIT loss is present in package:intl data between 0.19.0 and 0.20.x (lib/src/data/dates/symbols/ar.json), which suggests the shared data-generation pipeline dropped the arab numbering system for generic ar — only ar_EG retains ZERODIGIT: '٠'. This looks unintentional, since CLDR still specifies arab as the default numbering system for ar.

Code sample

Code sample
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      locale: const Locale('ar'),
      supportedLocales: const [Locale('ar'), Locale('en')],
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      home: Scaffold(
        body: Center(
          child: Builder(
            builder: (context) => Text(
              // Flutter <= 3.38: "٨:٣٠ م"  —  Flutter 3.44: "8:30 م"
              DateFormat.jm('ar').format(DateTime(2026, 1, 1, 20, 30)),
            ),
          ),
        ),
      ),
    );
  }
}

Logs

No exceptions are thrown; this is a silent data regression.

Flutter Doctor output

Doctor output
Flutter 3.44.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 924134a44c (11 days ago) • 2026-05-29 12:13:22 -0400
Engine • hash 39b1f7043775b9578bbb26a1676e79c4e31c8b5e (revision c416acfeb8) (13 days ago) • 2026-05-27 20:19:31.000Z
Tools • Dart 3.12.1 • DevTools 2.57.0

[✓] Flutter (Channel stable, 3.44.1, on macOS 26.1 25B78 darwin-arm64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 26.3)
[✓] Chrome - develop for the web
[✓] Connected device (3 available)
[✓] Network resources

• No issues found!

Activity

  1. saurabh-mirajkar commented on Jun 10, 2026

    @saurabh-mirajkar
    Contributor

    @ziyad-aljohani Thanks for the detailed report. I can reproduce this using the provided sample. On Flutter 3.38.10 the formatted time uses Arabic-Indic digits, while on Flutter 3.44.1 it renders Latin digits as described. Labeling and routing for investigation.

  2. added
    c: regressionIt was better in the past than it is now
    a: internationalizationSupporting other languages or locales. (aka i18n)
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    and removed
    in triagePresently being triaged by the triage team
    on Jun 10, 2026
  3. Piinks commented on Jun 23, 2026

    @Piinks
    Contributor
  4. added
    P1High-priority issues at the top of the work list
    on Jun 23, 2026
  5. QuncCccccc commented on Jun 24, 2026

    @QuncCccccc
    Contributor

    This seems because the upstream package intl removed ZERODIGIT in this commit.

  6. Piinks commented on Jun 24, 2026

    @Piinks
    Contributor

    Ah ok! Thanks for taking a look. Should we file an issue for intl to address it?

  7. QuncCccccc commented on Jun 24, 2026

    @QuncCccccc
    Contributor

    Yes! Will create an issue for intl!

  8. QuncCccccc commented on Jun 24, 2026

    @QuncCccccc
    Contributor
  9. ziyad-aljohani commented on Jun 27, 2026

    @ziyad-aljohani
    Author

    @QuncCccccc he said:
    ⁠"This is WAI, as the default for Arabic is latin numbering, so it as a latin 0 as the ZERODIGIT.⁠"
    Which is totally wrong. The default for Arabic should be Eastern Arabic numerals (٠, ١, ٢).
    In fact, both iOS and Android provide a system settings choice between standard Western numerals (1, 2, 3) and Eastern Arabic numerals (١, ٢, ٣). Flutter should support this choice.
    However, for now, it should revert to making Eastern Arabic numerals (٠, ١, ٢) the default, just as it was previously.

  10. ziyad-aljohani commented on Jun 29, 2026

    @ziyad-aljohani
    Author

    @QuncCccccc I understand that this stems from the upstream CLDR data mapping for the generic ar locale. However, relying solely on defaultNumberingSystem from CLDR for a generic locale leads to a broken user experience in production.

    Crucially, this change breaks the RTL (Right-to-Left) text rendering in the Text widget. For instance, if a user types a time string like 8:00 صباحا, the directionality breaks and it layout/starts from left to right due to the Latin digits forcing LTR text direction segments.

    • Old behavior (Correct RTL): ٨:٠٠ صباحا
    • New behavior (Broken layout): 8:00 صباحا

    Here is why this needs to be handled differently in Flutter:

    1. Platform Consistency: Both iOS and Android allow users to explicitly choose their preferred numbering system under Arabic regional settings. If a user has their system set to Eastern Arabic numerals (٠, ١, ٢), Flutter should respect the host platform's configuration rather than strictly falling back to the CLDR's generic latn default.
    2. The native Key in CLDR: As you pointed out, CLDR explicitly defines <native>arab</native> under otherNumberingSystems for the ar locale. For the vast majority of Arabic-speaking regions (outside of Northwest Africa/Maghreb), Eastern Arabic numerals are the expected native standard in daily digital interfaces.

    If Flutter strictly enforces latn for ar without checking the platform's native locale settings or fallback preferences, it breaks backward compatibility and forces an unnatural default on millions of users who previously had the correct native layout.

    Flutter should ideally check the native platform's numbering system preference, or at least respect the native token defined in CLDR when the generic ar locale is initialized without a specific country code.

  11. QuncCccccc commented on Jun 29, 2026

    @QuncCccccc
    Contributor

    Hello, I think I already fixed the missing ZERODIGIT issue on framework side. Please check master branch to verify.

  12. ziyad-aljohani commented on Jun 29, 2026

    @ziyad-aljohani
    Author

    @QuncCccccc Thank you.
    The problem is that i18n says this is the expected behaviour. So i think flutter should support both numbers based on device settings.

  13. Piinks commented on Jun 29, 2026

    @Piinks
    Contributor

    Thanks @ziyad-aljohani. I think I can clarify, the i18n package is not own or maintained by Flutter, it is a Dart package. For now, we have mitigated the change in i18n here in Flutter.

  14. github-actions commented on Jul 14, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  15. locked as resolved and limited conversation to collaborators on Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority issues at the top of the work lista: internationalizationSupporting other languages or locales. (aka i18n)c: regressionIt was better in the past than it is nowfound in release: 3.44Found to occur in 3.44has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions