Texto de: Lucas Galdino
Introdução
Deixar um horário ou data no exato formato em que queremos acaba sendo um grande desafio dentro do mundo de programação, e nesse artigo vou dar algumas dicas de como trabalhar com a formatação das datas no Flutter.
Criando o projeto
Vamos criar um pequeno projeto apenas para ilustrar melhor como iremos trabalhar. Primeiramente vamos utilizar o comando para criação de um novo projeto. Vou nomear o projeto como "datas" por motivos de didática mesmo. Basta abrir o terminal, navegar até a pasta aonde quer que seu projeto fique e utilizar o seguinte comando:
flutter create datas
Após o projeto ser criado já podemos abrir a nova pasta no VSCode e começar a trabalhar no código. A estrutura de pastas e arquivos do projeto deve ficar mais ou menos dessa maneira com um projeto recém-criado.
Código base
Primeiramente vamos alterar o código do arquivo pubspec.yaml já que iremos precisar importar o intl que é o pacote que contém as funções de formatação que iremos utilizar. Também iremos utilizar o localizations do próprio Flutter para podermos traduzir as datas. Basta clicar no nome dos pacotes caso queiram dar uma lida na documentação oficial. Como o pacote localizations necessita de uma versão específica do intl vamos fazer a instalação conforme o proposto na página oficial do localizations.
Como o arquivo pubspec.yaml é criado com vários comentários, ele pode ficar um pouco difícil de entender. Por isso, vamos deletar todo o conteúdo do arquivo, e adicionar no arquivo limpo o conteúdo abaixo:
name: datas
description: "A new Flutter project."
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: '>=3.2.4 <4.0.0'
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
flutter_localizations:
sdk: flutter
intl: any
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter:
uses-material-design: true
Agora vamos alterar o arquivo main.dart. Aqui também podemos deletar todo o conteúdo do arquivo e colar o conteúdo abaixo.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Formatação de Datas',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
brightness: Brightness.dark,
),
useMaterial3: true,
),
home: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.primary,
title: const Text("Formatação de Datas"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: MediaQuery.of(context).size.width * 0.1,
width: MediaQuery.of(context).size.width * 0.75,
margin: const EdgeInsets.all(4),
color: Colors.grey[800],
child: const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Datas"),
],
),
),
],
),
),
),
);
}
}
Com essas alterações, o aplicativo que você deverá ver ao executar é o seguinte:
Agora vamos fazer uma alteração para ajudar na legibilidade do código. Vamos refatorar o código para extrair o Container que vai conter os exemplos em um novo widget. Para isso é necessário apenas criar um novo arquivo chamado nova_data.dart lado a lado com o arquivo main.dart.
O conteúdo desse arquivo vai ser o Container utilizado anteriormente no arquivo main com algumas pequenas adições:
import 'package:flutter/material.dart';
class NovaData extends StatelessWidget {
final String data;
const NovaData(this.data, {super.key});
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.width * 0.1,
width: MediaQuery.of(context).size.width * 0.75,
margin: const EdgeInsets.all(4),
color: Colors.grey[800],
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(data),
],
),
);
}
}
Começando a implementar
A próxima coisa se fazer no código será a importação dos pacotes que iremos utilizar e também do widget separado para as datas lá na parte superior do arquivo main:
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
import 'nova_data.dart';
Após importar já salvem seu código para que o VSCode execute o comando pub get
automaticamente e baixe os pacotes necessários. No próximo passo nós vamos criar uma variável e definir o valor dela como a data atual. Para isso, vamos colocar o seguinte trecho de código abaixo do Widget build
da página e logo acima do return MaterialApp
. É importante avisar que como o valor da variável está sendo definido a partir da data atual, você pode obter uma data diferente da mostrada nos exemplos.
@override
Widget build(BuildContext context) {
DateTime data = DateTime.now();
return MaterialApp(
Com isso já temos a data que iremos utilizar para fazer diversas formatações!
Formatando de fato
Antes de mais nada podemos refatorar um pouco o código e substituir o uso do Container que está no arquivo main pelo widget externo que criamos. Basta deixar o body dessa forma:
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
NovaData("Datas"),
],
),
),
O widget Center foi marcado com a palavra const, pois nada dentro dele utiliza variáveis por enquanto, então para evitar os avisos sublinhados do VSCode, o widget foi marcado como constante.
Vamos fazer todos os exemplos apenas adicionando novos widgets NovaData passando parâmetros diferentes que representam as diferentes formas de se formatar as datas. Seguindo em frente, podemos adicionar nosso primeiro exemplo:
NovaData(DateFormat("'Data numérica:' dd/MM/yyyy").format(data)),
Aqui será necessário remover a marcação de const do widget Center e movê-lo para o widget NovaData que contém uma String simples como parâmetro, afinal agora vamos estar utilizando a variável data dentro dos outros exemplos.
Aqui funciona da seguinte forma: o que está dentro das aspas duplas vai ser o código referente ao DateFormat do pacote intl, ou seja, o dd significa dia, MM significa mês e yyyy significa ano. Para podermos interpolar esses dados com texto precisamos deixar o texto entre aspas simples que ficam dentro das aspas duplas anteriores. Sim, é um pouco confuso, mas ao visualizar o trecho de código acima da para entender melhor. O resultado no App vai ser o seguinte:
Vamos agora adicionar outras formatações, basta adicionarmos outra instância do widget NovaData e passar como parâmetro a nova formatação, dessa forma:
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const NovaData("Datas"),
NovaData(DateFormat("'Data numérica:' dd/MM/yyyy").format(data)),
NovaData(DateFormat("'Data por extenso:' d 'de' MMMM 'de' y")
.format(data)),
],
),
),
Aqui o código somente da nova formatação:
NovaData(DateFormat("'Data por extenso:' d 'de' MMMM 'de' y").format(data)),
Com esse código teremos como resultado o mês escrito por extenso. Porém, em inglês, o qual é o padrão da linguagem. O resultado é o seguinte:
Traduzindo para português
Para fazer a tradução para pt-BR vamos precisar adicionar alguns trechos de código no projeto. É agora que iremos utilizar o flutter_localizations que foi importado mais acima no artigo. Com o import feito vamos adicionar o seguinte trecho de código lá na Class MyApp:
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate
],
supportedLocales: const [Locale('pt', 'BR')],
Basta deixar esse trecho entre o return MaterialApp
e o themeData
, mais ou menos dessa forma:
return MaterialApp(
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate
],
supportedLocales: const [Locale('pt', 'BR')],
debugShowCheckedModeBanner: false,
title: 'Formatação de datas',
theme: ThemeData(
Com isso feito, tudo o que precisamos fazer agora é simplesmente alterar um pouco o DateFormat que estávamos fazendo. O que antes estava assim:
DateFormat("'Data por extenso:' d 'de' MMMM 'de' y").format(data)
Nós vamos deixar assim:
DateFormat("'Data por extenso:' d 'de' MMMM 'de' y", "pt_BR").format(data)
Ou seja, tudo que precisamos fazer agora é indicar dentro do DateFormat a língua na qual queremos que o resultado seja impresso. Com isso o resultado no App vai ser esse:
Mais alguns exemplos
Outra formatação útil é a da abreviação do mês, que podemos fazer da seguinte forma:
NovaData(DateFormat("'Mês:' MMMM '//' 'Abreviação:' MMM", "pt_BR").format(data)),
O resultado será:
E como último exemplo, mas não menos importante, o dia da semana:
NovaData(DateFormat("'Dia da semana:' EEEE", "pt_BR").format(data)),
Resultado:
Finalizando
Vou deixar aqui o código final do arquivo main.dart:
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
import 'nova_data.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
DateTime data = DateTime.now();
return MaterialApp(
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const [Locale('pt', 'BR')],
debugShowCheckedModeBanner: false,
title: 'Formatação de Datas',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
brightness: Brightness.dark,
),
useMaterial3: true,
),
home: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.primary,
title: const Text("Formatação de Datas"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const NovaData("Datas"),
NovaData(DateFormat("'Data numérica:' dd/MM/yyyy").format(data)),
NovaData(
DateFormat("'Data por extenso:' d 'de' MMMM 'de' y", 'pt_BR')
.format(data)),
NovaData(DateFormat("'Mês:' MMMM '//' 'Abreviação:' MMM", "pt_BR")
.format(data)),
NovaData(
DateFormat("'Dia da semana:' EEEE", "pt_BR").format(data)),
],
),
),
),
);
}
}
Conclusão
Nesse artigo vimos algumas formas de se formatar e traduzir datas numa aplicação desenvolvida utilizando Flutter. Agora você está preparado para fazer a formatação de datas da sua próxima aplicação.