Skip to content

MediaQuery.alwaysUse24HourFormat is not refreshed when the platform's 24-hour setting changes at runtime #194637

Open

Description

@ericchoi35

Steps to reproduce

  1. Run the sample below on iOS or Android with the device set to 12-hour time.
  2. With the app still running, switch the device to 24-hour time in Settings.
  3. Return to the app.

Expected results

MediaQuery.alwaysUse24HourFormatOf(context) reflects the platform's current setting (as PlatformDispatcher.alwaysUse24HourFormat does), so the sample reads 24-hour, and TimeOfDay.format / showTimePicker switch to the 24-hour clock.

Actual results

MediaQuery keeps the previous value until one of metrics, text scale, platform brightness or accessibility features changes, or the app restarts, so every MediaQuery-driven time format stays on the old clock.

I have reproduced this deterministically with the widget test below, which drives the same framework path the engine does on this change; I have not captured it on a physical device.

Code sample

App
import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(home: Probe()));

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

  @override
  Widget build(BuildContext context) => Scaffold(
        body: Center(
          child: Text(MediaQuery.alwaysUse24HourFormatOf(context)
              ? '24-hour'
              : '12-hour'),
        ),
      );
}
Widget test (fails on 3.44.6)
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('MediaQuery sees a 24-hour change', (tester) async {
    addTearDown(tester.platformDispatcher.clearAlwaysUse24HourTestValue);
    await tester.pumpWidget(MaterialApp(
      home: Builder(
        builder: (context) =>
            Text('${MediaQuery.alwaysUse24HourFormatOf(context)}'),
      ),
    ));
    expect(find.text('false'), findsOneWidget);

    // What the engine does when only this setting changes: update the value
    // and invoke onPlatformConfigurationChanged.
    tester.platformDispatcher.alwaysUse24HourFormatTestValue = true;
    tester.platformDispatcher.onPlatformConfigurationChanged?.call();
    await tester.pump();

    expect(find.text('true'), findsOneWidget); // fails: still 'false'
  });
}

Analysis (3.44.6)

  • dart:ui PlatformDispatcher._updateUserSettingsData: when only alwaysUse24HourFormat changes, it updates the configuration and invokes onPlatformConfigurationChanged; onTextScaleFactorChanged, onPlatformBrightnessChanged and onSystemFontFamilyChanged are each gated on their own value changing.
  • Nothing in packages/flutter/lib listens to onPlatformConfigurationChanged.
  • _MediaQueryFromViewState (widgets/media_query.dart) re-reads MediaQueryData.fromView only from didChangeDependencies, didChangeMetrics, didChangeTextScaleFactor, didChangePlatformBrightness and didChangeAccessibilityFeatures.
  • Related, in flutter_test: the TestPlatformDispatcher.alwaysUse24HourFormatTestValue setter only stores the value (unlike textScaleFactorTestValue, which calls onTextScaleFactorChanged), so a test cannot observe a change without invoking a callback itself.

Workaround

Re-provide MediaQuery from a widget below MaterialApp (its builder:) that listens to onPlatformConfigurationChanged, chaining any existing handler, and overrides alwaysUse24HourFormat with PlatformDispatcher.alwaysUse24HourFormat.

Flutter Doctor output

Flutter 3.44.6 • channel stable

Activity

  1. saurabh-mirajkar commented on Oct 19, 2026

    @saurabh-mirajkar
    Contributor

    @ericchoi35 Thanks for the report. I reproduced this on Flutter 3.47.7 stable using the supplied test and on a physical Pixel 6 (Android 17). @sreevishnuqa also reproduced it on a physical iPhone (iOS 27.2) where the updated format appeared only after opening the app a second time.

    Labelling this and routing it to the framework team for further investigation.

    Related: #149179

    Android iOS
    android-date.mp4
    ios-date.mov
  2. added
    platform-androidAndroid applications specifically
    platform-iosiOS applications specifically
    frameworkflutter/packages/flutter repository. See also f: labels.
    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 Oct 19, 2026
  3. added 2 commits that reference this issue on Oct 19, 2026
    74a3959
    0517c3e
  4. added
    P2Important issues not at the top of the work list
    on Oct 20, 2026
  5. Renzo-Olivares commented on Oct 20, 2026

    @Renzo-Olivares
    Contributor

    Thank you for the report @ericchoi35! Looks like @prasad2512 has a PR in progress that will fix this.

  6. added a commit that references this issue on Oct 27, 2026
    f2da993
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

    P2Important issues not at the top of the work lista: internationalizationSupporting other languages or locales. (aka i18n)frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-androidAndroid applications specificallyplatform-iosiOS applications specificallyteam-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