Skip to main content

Format Settings

FdcFormatSettings defines FDC data-entry and display formatting conventions for:

  • dates,
  • times,
  • date-time values,
  • decimal separators,
  • thousands separators,
  • thousands grouping visibility.

It is independent from UI translations. A locale may resolve a format preset even when FDC UI text falls back to English.

Default behavior

Without explicit settings, FDC resolves formatting from the active Flutter locale through FdcDefaultFormatResolver.

FdcApp(
child: const OrdersPage(),
)

The resolver first checks the curated built-in FDC locale format registry. Unsupported locales fall back to neutral technical formatting.

The neutral fallback is:

dateFormat yyyy-MM-dd
timeFormat HH:mm
dateTimeFormat date + space + time
decimalSeparator .
thousandSeparator ,
showThousandSeparator true

The format system is synchronous and does not require intl locale-data initialization.

Resolve a locale preset

final formats = FdcFormatSettings.fromLocale(
const Locale('de', 'DE'),
);

For the current platform locale:

final formats = FdcFormatSettings.system();

You can also use locale-only shorthand:

const FdcFormatSettings(locale: 'de_DE')

When only locale is supplied and all other values remain at constructor defaults, FDC resolves the matching built-in locale preset.

Once you provide any concrete format override, the settings object becomes authoritative rather than being replaced by a locale preset.

Global application settings

Apply exact settings through FdcApp:

FdcApp(
formatSettings: const FdcFormatSettings(
locale: 'en_US',
dateFormat: 'MM/dd/yyyy',
timeFormat: 'h:mm a',
dateTimeFormat: 'MM/dd/yyyy h:mm a',
decimalSeparator: '.',
thousandSeparator: ',',
showThousandSeparator: true,
),
child: const OrdersPage(),
)

All descendant FDC controls use those settings unless a component-level API explicitly overrides them.

Format properties

dateFormat

Pattern used for date values:

const FdcFormatSettings(
dateFormat: 'dd.MM.yyyy',
)

timeFormat

Pattern used for time values:

const FdcFormatSettings(
timeFormat: 'HH:mm',
)

dateTimeFormat

Optional combined date-time pattern:

const FdcFormatSettings(
dateFormat: 'dd.MM.yyyy',
timeFormat: 'HH:mm',
dateTimeFormat: 'dd.MM.yyyy HH:mm',
)

When dateTimeFormat is null, effectiveDateTimeFormat is:

dateFormat + " " + timeFormat

decimalSeparator

Character used between integer and fractional decimal parts:

const FdcFormatSettings(
decimalSeparator: ',',
)

thousandSeparator

Grouping separator used for numeric presentation:

const FdcFormatSettings(
thousandSeparator: '.',
)

showThousandSeparator

Controls whether grouped numeric presentation is enabled:

const FdcFormatSettings(
showThousandSeparator: false,
)

Example: European numeric formatting

const european = FdcFormatSettings(
dateFormat: 'dd.MM.yyyy',
timeFormat: 'HH:mm',
decimalSeparator: ',',
thousandSeparator: '.',
showThousandSeparator: true,
);

A decimal value can then be displayed as:

1.234.567,89

The underlying dataset value remains an exact FdcDecimal; separators are presentation and input conventions, not part of the stored decimal value.

Example: US numeric formatting

const us = FdcFormatSettings(
locale: 'en_US',
dateFormat: 'MM/dd/yyyy',
timeFormat: 'h:mm a',
decimalSeparator: '.',
thousandSeparator: ',',
showThousandSeparator: true,
);

Presentation example:

1,234,567.89

Application resolver

For an application-specific locale policy, implement FdcFormatResolver:

class AppFormatResolver implements FdcFormatResolver {
const AppFormatResolver();

@override
FdcFormatSettings resolve(Locale locale) {
if (locale.languageCode == 'en' && locale.countryCode == 'US') {
return FdcFormatSettings.fromLocale(locale);
}

return const FdcFormatSettings(
dateFormat: 'dd.MM.yyyy',
timeFormat: 'HH:mm',
decimalSeparator: ',',
thousandSeparator: '.',
);
}
}

Register it once:

FdcApp(
formatResolver: const AppFormatResolver(),
child: const OrdersPage(),
)

The resolver is synchronous and deterministic.

Local component override

Some editors and columns expose formatSettings directly. Use that only when a specific control intentionally differs from the application convention:

FdcDecimalEdit(
dataSet: orders,
fieldName: 'exchange_rate',
formatSettings: const FdcFormatSettings(
decimalSeparator: '.',
thousandSeparator: ',',
showThousandSeparator: false,
),
)

The usual precedence is:

component formatSettings override
→ FdcApp explicit formatSettings
→ FdcApp formatResolver + active locale
→ built-in locale preset
→ neutral technical fallback

Deriving modified settings

Use copyWith when most settings should stay unchanged:

final base = FdcFormatSettings.fromLocale(
const Locale('de', 'DE'),
);

final compact = base.copyWith(
showThousandSeparator: false,
);

locale and dateTimeFormat can explicitly be cleared:

final neutralized = base.copyWith(
locale: null,
dateTimeFormat: null,
);

Reading effective settings

Use:

final formats = FdcApp.formatsOf(context);

Custom UI can then use the same application conventions as FDC controls.

For initialization paths that must not subscribe to inherited changes:

final formats = FdcApp.formatsOfNonListening(context);

Interaction with FdcDecimal

Formatting does not change decimal arithmetic.

final amount = '1234.50'.decimal;

The value remains exact regardless of whether it is presented as:

1,234.50
1.234,50
1 234,50

FdcFormatSettings governs input/display conventions. FdcDecimal governs exact value semantics and arithmetic.