Introdução

Nem sempre é fácil deixar um horário ou data no formato em que queremos tanto em Flutter como eu outras tecnologias. Nesse artigo vou dar algumas dicas de como trabalhar melhor a questão da formatação das datas porém focando no Flutter mesmo. Vou estar utilizando o Flutter juntamente com o VSCode para editar nossos códigos!

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 comando:

flutter create datas

Após o projeto ser criado já podemos abrir a nova pasta no VSCode e começar a trabalhar nosso código. A estrutura do projeto deve ficar da seguinte maneira (uma pasta chamada ‘test’ também será criada, mas podem deletar ela sem problemas):

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.

Enfim, deixem o arquivo dessa maneira aqui:

name: datas
description: A new Flutter project.

publish_to: 'none'

version: 1.0.0+1

environment:
  sdk: ">=2.3.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  cupertino_icons: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter
  intl: ^0.16.0

flutter:


  uses-material-design: true

Agora vamos alterar o arquivo main.dart, podem apagar o arquivo por completo e deixar da seguinte maneira:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Formatação de datas',
      theme: ThemeData(
        brightness: Brightness.dark,
        accentColor: Colors.white,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: "Formatação de datas"),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(
              height: MediaQuery.of(context).size.width * 0.1,
              width: MediaQuery.of(context).size.width * 0.75,
              margin: EdgeInsets.all(4),
              color: Colors.grey[800],
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text("Datas"),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Com essas alterações o App que você deverá ver ao executar é o seguinte:

Fiz apenas algumas alterações visuais e preparei o espaço aonde os exemplos irão ficar, não tem muito o que explicar por enquanto.

Começando a implementar

A primeira coisa se fazer no código será a importação dos pacotes que iremos utilizar:

import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';

Após importar já salvem seu código para que o VSCode rode o pub get automaticamente e baixe os pacotes.

No próximo passo nós vamos criar uma variável e definir o valor dela como a data atual. Para isso é bem simples, vamos colocar o seguinte trecho de código abaixo State da página e logo acima do override:

class _MyHomePageState extends State<MyHomePage> {
  DateTime data = DateTime.now();
  @override

Com isso já temos a data que iremos utilizar para fazer diversas formatações!

Formatando de fato

Para primeiro exemplo basta substituir o Text que contém a string ‘Datas’ pelo seguinte:

Text(DateFormat("'Data numérica:' dd/MM/yyyy").format(data)),

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 dentro das aspas duplas anteriores. Beleza?

O resultado no App vai ser o seguinte:

Vamos agora adicionar outras formatações, basta adiciornarmos outros Containers dentro da nossa Column, após a virgula do primeiro Container basta colar esse trecho de código:

Container(
              height: MediaQuery.of(context).size.width * 0.1,
              width: MediaQuery.of(context).size.width * 0.75,
              margin: EdgeInsets.all(4),
              color: Colors.grey[800],
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(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, que é o padrão da linguagem. O resultado é o seguinte:

Traduzindo para português

Para fazer a tradução para ptBR vamos precisar adicionar algumas coisas no nosso projeto. É agora que iremos utilizar o import do flutter_localizations que já foi feito mais acima no artigo. Com o import feito vamos adicionar o seguinte trecho de código lá na Class MyApp, ou seja, lá em cima no código:

localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate
      ],
      supportedLocales: [const Locale('pt', 'BR')],

Basta deixar esse trecho entre o return do MaterialApp e o themeData, mais ou menos dessa forma:

return MaterialApp(
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate
      ],
      supportedLocales: [const Locale('pt', 'BR')],
      debugShowCheckedModeBanner: false,
      title: 'Formatação de datas',
      theme: ThemeData(

É aqui que o código precisa ficar.

Com isso feito tudo o que precisamos fazer agora é simplesmente alterar um pouco o DateFormat que estavámos 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 lingua 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:

Container(
              height: MediaQuery.of(context).size.width * 0.1,
              width: MediaQuery.of(context).size.width * 0.75,
              margin: EdgeInsets.all(4),
              color: Colors.grey[800],
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(DateFormat("'Mês:' MMMM '//' 'Abreviação:' MMM", "pt_BR")
                      .format(data)),
                ],
              ),
            ),

O resultado será:

E por último mas não menos importante, o dia da semana:

Container(
              height: MediaQuery.of(context).size.width * 0.1,
              width: MediaQuery.of(context).size.width * 0.75,
              margin: EdgeInsets.all(4),
              color: Colors.grey[800],
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(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';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate
      ],
      supportedLocales: [const Locale('pt', 'BR')],
      debugShowCheckedModeBanner: false,
      title: 'Formatação de datas',
      theme: ThemeData(
        brightness: Brightness.dark,
        accentColor: Colors.white,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: "Formatação de datas"),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  DateTime data = DateTime.now();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(
              height: MediaQuery.of(context).size.width * 0.1,
              width: MediaQuery.of(context).size.width * 0.75,
              margin: EdgeInsets.all(4),
              color: Colors.grey[800],
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(DateFormat("'Data numérica:' dd/MM/yyyy").format(data)),
                ],
              ),
            ),
            Container(
              height: MediaQuery.of(context).size.width * 0.1,
              width: MediaQuery.of(context).size.width * 0.75,
              margin: EdgeInsets.all(4),
              color: Colors.grey[800],
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(DateFormat(
                          "'Data por extenso:' d 'de' MMMM 'de' y", "pt_BR")
                      .format(data)),
                ],
              ),
            ),
            Container(
              height: MediaQuery.of(context).size.width * 0.1,
              width: MediaQuery.of(context).size.width * 0.75,
              margin: EdgeInsets.all(4),
              color: Colors.grey[800],
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(DateFormat("'Mês:' MMMM '//' 'Abreviação:' MMM", "pt_BR")
                      .format(data)),
                ],
              ),
            ),
            Container(
              height: MediaQuery.of(context).size.width * 0.1,
              width: MediaQuery.of(context).size.width * 0.75,
              margin: EdgeInsets.all(4),
              color: Colors.grey[800],
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(DateFormat("'Dia da semana:' EEEE", "pt_BR")
                      .format(data)),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Lembrando pessoal que como extraímos no início o dia atual o resultado irá variar de acordo com o dia em que vocês estejam lendo esse artigo, então não pensem que algo está errado caso o resultado saia diferente do mostrado nos prints! Caso queiram ler mais sobre os códigos utilizados pelo ‘intl’ para fazer as formatações estarei deixandos links logo abaixo! Bons estudos galera!

Links úteis

https://pub.dev/packages/intl

https://flutter.dev/docs/development/accessibility-and-localization/internationalization

https://pub.dev/documentation/intl/latest/intl/DateFormat-class.html