Flutter provides robust support for internationalization (i18n) and localization (l10n), enabling developers to create applications that adapt to different languages, regions, and cultural preferences. Localizing data such as dates, numbers, and currencies is crucial for providing a seamless user experience. In this blog post, we will explore how to localize dates, numbers, currencies, and other data based on the locale in Flutter.
What is Localization?
Localization involves adapting an application to a specific locale, including translating text, adjusting date and time formats, currency symbols, number formats, and other locale-specific elements. It ensures that the application is culturally appropriate and user-friendly for a specific region or language.
Setting up Internationalization in Flutter
Before localizing dates, numbers, or currencies, we need to set up internationalization in the Flutter project.
Step 1: Add Dependencies
Add the necessary dependencies to your pubspec.yaml
file:
dependencies:
flutter:
sdk: flutter
intl: ^0.17.0 # or a newer version
flutter_localizations:
sdk: flutter
Then, run flutter pub get
to install the dependencies.
Step 2: Configure flutter_localizations
Configure the flutter_localizations
in your MaterialApp
:
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'), // English, United States
const Locale('es', 'ES'), // Spanish, Spain
const Locale('fr', 'FR'), // French, France
],
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Localization Demo'),
),
body: Center(
child: Text('Hello, World!'), // This will be localized later
),
);
}
}
Localizing Dates in Flutter
Dates can be formatted differently based on the locale. The intl
package provides the DateFormat
class for localizing dates.
Basic Date Formatting
Here’s how to format a date according to the current locale:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class DateLocalizationExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
final now = DateTime.now();
final locale = Localizations.localeOf(context);
final formatter = DateFormat.yMMMd(locale.toString());
final formattedDate = formatter.format(now);
return Scaffold(
appBar: AppBar(
title: Text('Date Localization'),
),
body: Center(
child: Text('Formatted Date: $formattedDate'),
),
);
}
}
In this example, DateFormat.yMMMd(locale.toString())
creates a formatter that displays the year, month, and day in the format specific to the current locale.
Custom Date Formatting
You can also use custom patterns to format dates:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class CustomDateFormatting extends StatelessWidget {
@override
Widget build(BuildContext context) {
final now = DateTime.now();
final locale = Localizations.localeOf(context);
final formatter = DateFormat('EEEE, MMMM d, y', locale.toString()); // Example: Friday, July 9, 2024
final formattedDate = formatter.format(now);
return Scaffold(
appBar: AppBar(
title: Text('Custom Date Formatting'),
),
body: Center(
child: Text('Formatted Date: $formattedDate'),
),
);
}
}
Common date formatting patterns:
y
: YearM
: Monthd
: DayE
: Day of the weekH
: Hour (24-hour format)m
: Minutes
: Second
Localizing Numbers in Flutter
Numbers also vary in formatting based on the locale, including decimal separators, thousands separators, and more. The NumberFormat
class from the intl
package is used to format numbers according to the locale.
Basic Number Formatting
Here’s how to format a number:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class NumberLocalizationExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
final number = 12345.678;
final locale = Localizations.localeOf(context);
final formatter = NumberFormat.decimalPattern(locale.toString());
final formattedNumber = formatter.format(number);
return Scaffold(
appBar: AppBar(
title: Text('Number Localization'),
),
body: Center(
child: Text('Formatted Number: $formattedNumber'),
),
);
}
}
In this example, NumberFormat.decimalPattern(locale.toString())
creates a formatter that formats numbers with the appropriate decimal and thousands separators for the given locale.
Custom Number Formatting
You can also format numbers to a specific number of decimal places:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class CustomNumberFormatting extends StatelessWidget {
@override
Widget build(BuildContext context) {
final number = 12345.678;
final locale = Localizations.localeOf(context);
final formatter = NumberFormat('###,###.00', locale.toString());
final formattedNumber = formatter.format(number);
return Scaffold(
appBar: AppBar(
title: Text('Custom Number Formatting'),
),
body: Center(
child: Text('Formatted Number: $formattedNumber'),
),
);
}
}
Localizing Currencies in Flutter
Currency formatting varies widely based on locale, including the currency symbol, placement of the symbol, and the decimal format.
Basic Currency Formatting
Here’s how to format a currency amount:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class CurrencyLocalizationExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
final amount = 1234.56;
final locale = Localizations.localeOf(context);
final formatter = NumberFormat.currency(locale: locale.toString());
final formattedCurrency = formatter.format(amount);
return Scaffold(
appBar: AppBar(
title: Text('Currency Localization'),
),
body: Center(
child: Text('Formatted Currency: $formattedCurrency'),
),
);
}
}
In this example, NumberFormat.currency(locale: locale.toString())
creates a formatter that formats the amount as currency, using the symbol and format appropriate for the given locale.
Specifying Currency Symbol
If you need to specify a specific currency symbol, you can do so like this:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class SpecificCurrencyFormatting extends StatelessWidget {
@override
Widget build(BuildContext context) {
final amount = 1234.56;
final locale = Localizations.localeOf(context);
final formatter = NumberFormat.currency(locale: locale.toString(), symbol: 'EUR');
final formattedCurrency = formatter.format(amount);
return Scaffold(
appBar: AppBar(
title: Text('Specific Currency Formatting'),
),
body: Center(
child: Text('Formatted Currency: $formattedCurrency'),
),
);
}
}
Localizing Other Data
Besides dates, numbers, and currencies, you can localize other types of data as well. For example, you can localize pluralization rules or units of measurement.
Pluralization
The intl
package can also help with handling pluralization. However, for more complex text, consider using more sophisticated localization techniques, such as .arb
files and code generation (which is outside the scope of this post).
import 'package:flutter/material.dart';
class PluralizationExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
final count = 5;
final message = Intl.plural(
count,
zero: 'No items',
one: 'One item',
other: '$count items',
locale: Localizations.localeOf(context).toString(),
);
return Scaffold(
appBar: AppBar(
title: Text('Pluralization Example'),
),
body: Center(
child: Text(message),
),
);
}
}
Conclusion
Localizing dates, numbers, and currencies in Flutter involves using the intl
package along with Flutter’s localization features. By formatting these types of data according to the locale, you can provide a more natural and intuitive user experience for users around the world. Ensure that your app is set up for internationalization properly, and use DateFormat
, NumberFormat
, and other tools to adapt your app’s display to cultural preferences.