Java Data e Hora

⚡ Resumo Inteligente

Java O tratamento de data e hora combina as classes legadas java.util.Date e SimpleDateFormat com a moderna API java.time introduzida em Java 8, oferecendo aos desenvolvedores tipos imutáveis ​​e thread-safe para trabalhos precisos com calendários.

  • 🕒 Data Legada: A classe java.util.Date armazena um instante em milissegundos e imprime uma string padrão através do método toString.
  • 🔤 Letras do padrão: O SimpleDateFormat usa letras como aaaa, MM, dd, HH, mm, ss e zzz para definir formatos de saída personalizados.
  • ⚖️ Comparação: O método compareTo retorna um número inteiro negativo, zero ou positivo para ordenar duas instâncias de Date cronologicamente.
  • 🆕 API moderna: LocalDate, LocalDateTime, ZonedDateTime e Instant em java.time substituem Date e Calendar por objetos imutáveis.
  • 🧵 Segurança da linha: DateTimeFormatter é imutável e seguro para compartilhar, enquanto SimpleDateFormat precisa de sincronização ou de um wrapper ThreadLocal.
  • 🔁 Interoperabilidade: Converta entre as APIs antigas e novas usando as funções auxiliares Date.toInstant, Date.from e Calendar.toInstant.

Java Data e Hora

Lidar com datas e horários em Java É uma parte rotineira da construção da lógica de agendamento, registro de data e hora, relatórios e trilhas de auditoria. Antes de escrever qualquer código, é útil conhecer os parâmetros que compõem uma data:

  • O ano (em dois ou quatro dígitos).
  • O mês (com dois dígitos, com as três primeiras letras do mês ou com o nome completo do mês).
  • O dados (o número do dia do mês correspondente).
  • O dia (o nome do dia da semana na data indicada, como Dom, Seg, Ter).

Java Expõe muitos outros parâmetros que descrevem um momento na linha do tempo, incluindo era, semana do ano, fuso horário e deslocamento. As seções abaixo abordam cada um deles com exemplos executáveis.

Como usar a data em Java

Exibir data em Java

Java fornece uma Date classe na java.util O pacote armazena um instante específico no tempo com precisão de milissegundos e oferece métodos auxiliares para imprimir, comparar e formatar esse instante. Para obter a data e hora atuais, instancie a classe com seu construtor padrão:

import java.util.Date;

class Date_Ex1 {
    public static void main(String args[]) {
        // Instantiate a Date object by invoking its constructor
        Date objDate = new Date();
        // Display the Date and Time using toString()
        System.out.println(objDate.toString());
    }
}

Saída:

Wed Nov 29 06:36:22 UTC 2017

O exemplo imprime a data no formato padrão do toString. Para exibir a mesma data em um formato diferente, primeiro você precisa entender os caracteres de formatação que Java usa.

SimpleDateFormat: analisar e formatar datas

O SimpleDateFormat aula em java.text converte um Date converte um objeto em uma string formatada e analisa a string formatada de volta para um objeto. DateEle usa letras padronizadas que correspondem a um componente de data ou hora. A tabela abaixo lista todas as letras suportadas:

CartaComponente de data ou horaExemplo
GDesignador de eraAD
yAno2026
MMês no anoJulho ou julho ou 07
wSemana no ano27
WSemana no mês2
DDia no ano189
dDia no mês10
FDia da semana no mês2
ENome do dia na semanaTerça ou Terça
uNúmero do dia da semana (1 = Monday, 7 = Domingo)1
aMarcador AM ou PMPM
HHora do dia (0-23)0
kHora do dia (1-24)24
KHora em AM ou PM (0-11)0
hHora em AM ou PM (1-12)12
mMinuto em hora30
sSegundo em minuto55
SMilissegundo978
zFuso horário (nome)Hora padrão do Pacífico; PST; GMT-08: 00
ZFuso horário (deslocamento RFC 822)-0800
XFuso horário (deslocamento ISO 8601)-08 ou -0800 ou -08:00

Você não precisa memorizar a tabela inteira. Consulte-a sempre que criar um novo padrão.

Como usar o SimpleDateFormat

SimpleDateFormat é uma subclasse de DateFormat Isso permite formatar e analisar datas usando as letras padrão acima. Combine as letras para descrever a sequência exata que você deseja produzir ou ler.

Por exemplo:

  1. Formato de data exigido: 2012.10.23/20/20 45:XNUMX:XNUMX PSTO padrão de formato apropriado é yyyy.MM.dd HH:mm:ss zzz.
  2. Formato de data exigido: 09:30:00 AM 23-May-2012O padrão de formato apropriado é hh:mm:ss a dd-MMM-yyyy.

Dica: Atenção para maiúsculas e minúsculas. M é mês, em minúsculas m é minúsculo. Maiúsculo H é um relógio de 24 horas, em letras minúsculas. h É um relógio de 12 horas. Misturá-los produz resultados incorretos sem aviso prévio.

O programa abaixo imprime a data atual duas vezes, uma vez no formato padrão e outra usando um padrão SimpleDateFormat:

import java.text.SimpleDateFormat;
import java.util.Date;

class TestDates_Format {
    public static void main(String args[]) {
        // Current system date and time is assigned to objDate
        Date objDate = new Date();
        System.out.println(objDate);

        // Build the target pattern and format the date
        String strDateFormat = "hh:mm:ss a dd-MMM-yyyy";
        SimpleDateFormat objSDF = new SimpleDateFormat(strDateFormat);
        System.out.println(objSDF.format(objDate));
    }
}

Saída:

Wed Nov 29 06:31:41 UTC 2017
06:31:41 AM 29-Nov-2017

Exemplo de comparação de datas

Exemplo de comparação de datas

A maneira mais confiável de pedir dois Date objetos é o compareTo() O método retorna um número inteiro negativo quando a data solicitada é anterior, zero quando ambas as datas são iguais e um número inteiro positivo quando a data solicitada é posterior. O trecho de código abaixo analisa duas strings de data e imprime sua ordem relativa:

import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.Date;

class TestDates_Compare {
    public static void main(String args[]) throws ParseException {

        SimpleDateFormat objSDF = new SimpleDateFormat("dd-MM-yyyy");
        Date dt_1 = objSDF.parse("20-08-1981");
        Date dt_2 = objSDF.parse("12-10-2012");

        System.out.println("Date1 : " + objSDF.format(dt_1));
        System.out.println("Date2 : " + objSDF.format(dt_2));

        // compareTo returns > 0 when dt_1 is after dt_2
        if (dt_1.compareTo(dt_2) > 0) {
            System.out.println("Date 1 occurs after Date 2");
        }
        // compareTo returns < 0 when dt_1 is before dt_2
        else if (dt_1.compareTo(dt_2) < 0) {
            System.out.println("Date 1 occurs before Date 2");
        }
        // compareTo returns 0 when both dates are equal
        else {
            System.out.println("Both are the same date");
        }
    }
}

Saída:

Date1 : 20-08-1981
Date2 : 12-10-2012
Date 1 occurs before Date 2

Observação: O código original utilizava o padrão dd-mm-yyyy. As letras minúsculas mm A letra representa o minuto, não o mês, então o analisador sintático gerou silenciosamente o valor errado para o mês. A correção acima usa letras maiúsculas. MM para o mês, que é a letra do padrão correto.

Java 8 API moderna de data e hora (java.time)

Java 8 introduziu o java.time O pacote apresenta uma API redesenhada inspirada na biblioteca Joda-Time. As novas classes são imutáveis, thread-safe e separam o calendário humano da linha do tempo da máquina. Os tipos mais comuns são:

  • LocalDate Para uma data sem hora ou fuso horário especificados (por exemplo, um aniversário).
  • LocalTime Para exibir a hora em um relógio de parede, sem data ou fuso horário.
  • LocalDateTime Para uma data e hora sem fuso horário.
  • ZonedDateTime para uma data e hora com um fuso horário específico.
  • OffsetDateTime Para uma data e hora com um deslocamento UTC, mas sem fuso horário nomeado.
  • Instant para um registro de data e hora da máquina medido a partir da época UNIX.
  • Duration e Period para valores baseados em tempo e em data.

O exemplo abaixo imprime a data, hora, carimbo de data/hora e fuso horário atuais usando a API moderna:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.Instant;
import java.time.ZoneId;

class ModernDateDemo {
    public static void main(String args[]) {
        LocalDate today = LocalDate.now();
        LocalDateTime now = LocalDateTime.now();
        ZonedDateTime zoned = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
        Instant epoch = Instant.now();

        System.out.println("LocalDate     : " + today);
        System.out.println("LocalDateTime : " + now);
        System.out.println("ZonedDateTime : " + zoned);
        System.out.println("Instant       : " + epoch);
    }
}

Cada tipo possui métodos de fábrica (now, of, parse) e operações imutáveis ​​(plusDays, minusHours, withYear) que retornam um novo valor em vez de modificar o objeto original.

Formatador de Data e Hora: Formate datas no formato moderno Java

DateTimeFormatter in java.time.format substitui SimpleDateFormatEla usa o mesmo estilo de letras padrão, é imutável e pode ser compartilhada com segurança entre threads sem sincronização adicional. A classe também expõe constantes prontas para uso, como ISO_LOCAL_DATE e ISO_ZONED_DATE_TIME para formatos padrão.

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

class FormatterDemo {
    public static void main(String args[]) {
        LocalDateTime now = LocalDateTime.now();

        DateTimeFormatter iso = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        DateTimeFormatter human = DateTimeFormatter.ofPattern("hh:mm:ss a dd-MMM-yyyy");

        System.out.println(now.format(iso));
        System.out.println(now.format(human));

        LocalDateTime parsed = LocalDateTime.parse("2026-07-04T09:30:00", iso);
        System.out.println("Parsed back : " + parsed);
    }
}

Para comparar duas datas na API moderna, chame isBefore, isAfter, ou isEqualEsses métodos são mais fáceis de ler do que compareTo e trabalhar com todos java.time classe.

Segurança de roscas e melhores práticas para Java Data e Hora

Ambos java.util.Date e SimpleDateFormat anteriores aos modernos contemporâneos JavaE cada uma delas tem suas desvantagens conhecidas. Siga as práticas abaixo para manter o tratamento de datas correto no código de produção:

  • Prefira java.time a Date e Calendar. Os novos tipos são imutáveis ​​e seguros para uso em múltiplas threads, e modelam o domínio com maior precisão (datas sem horários, horários sem fusos horários, etc.).
  • Não compartilhe um SimpleDateFormat entre tópicos diferentes. A classe armazena o estado interno da análise sintática e não é thread-safe. Envolva-a em um ThreadLocal, sincronize na instância ou mude para DateTimeFormatter.
  • Sempre especifique uma localidade. Os nomes dos meses e dias mudam de acordo com a localidade padrão da JVM, o que cria padrões como MMM e EEE não portátil. Passe uma localidade explicitamente (por exemplo, Locale.ENGLISH).
  • Seja explícito quanto aos fusos horários. LocalDateTime Não possui zona, então converta para ZonedDateTime or Instant Sempre que o momento exato importa, especialmente para registros, colunas de banco de dados e dados de rede.
  • Converta entre as duas APIs com cuidado. Uso date.toInstant(), Date.from(instant) e calendar.toInstant().atZone(zone) na fronteira entre o código legado e o código moderno.
  • Armazene os registros de data e hora em UTC. Persista e transmit datas como UTC (um Instant ou uma string ISO 8601) e converter para a zona do usuário somente ao exibir.

Perguntas Frequentes

Chame LocalDateTime.now() do pacote java.time para obter uma data e hora no fuso horário do sistema, ou LocalDate.now() para obter apenas a data. Em versões mais antigas do sistema, isso pode ser feito chamando LocalDateTime.now() do pacote java.time. Java, use new java.util.Date() para obter o instante atual.

java.util.Date representa um instante em milissegundos desde a época Unix e é mutável. LocalDate modela uma data de calendário sem hora ou fuso horário, é imutável e thread-safe, e oferece métodos mais claros como plusDays e isBefore.

Não. O SimpleDateFormat mantém um estado de análise mutável e produz resultados incorretos quando compartilhado entre threads. Envolva-o em um ThreadLocal, sincronize na instância ou mude para DateTimeFormatter, que é imutável e seguro.

Passe a string exata “yyyy-MM-dd”. MM em maiúsculo representa o mês e mm em minúsculo representa os minutos. Para a data e hora completas, use “yyyy-MM-dd HH:mm:ss”. Sempre especifique uma localidade para que os nomes dos meses permaneçam consistentes.

Com o método `Date` legado, use `compareTo`, que retorna um inteiro negativo, zero ou positivo. Com `java.time`, chame `isBefore`, `isAfter` ou `isEqual` em um `LocalDate` ou `Instant`. Ambas as abordagens respeitam a ordem cronológica.

Chame `date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()`. Para voltar no tempo, use `Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant())`. Selecione o fuso horário explicitamente sempre que o momento exato for importante.

Modelos de IA treinados em corpora de logs e documentos inferem o padrão provável a partir de strings de amostra e retornam um padrão DateTimeFormatter correspondente. Classificadores de aprendizado de máquina também sinalizam campos ambíguos, como a ordem mês-dia versus dia-mês.

Sim. O GitHub Copilot sugere padrões DateTimeFormatter, conversões ZonedDateTime e JUnit Testes para saída sensível à localização. RevConfira cada sugestão para as letras do padrão correto, localidade e fuso horário antes de confirmar.

Resuma esta postagem com: