O Java 8 adicionou uma nova API java.time para trabalhar com datas e horas ( JSR 310 ).
Eu tenho data e hora como string (por exemplo "2014-04-08 12:30"
). Como posso obter uma LocalDateTime
instância da string especificada?
Depois que terminei de trabalhar com o LocalDateTime
objeto: Como posso converter a LocalDateTime
instância novamente em uma string com o mesmo formato, como mostrado acima?
ZonedDateTime
não umLocalDateTime
. O nome é contra-intuitivo; oLocal
significa qualquer localidade, em geral, ao invés de um fuso horário específico. Como tal, umLocalDateTime
objeto não está vinculado à linha do tempo. Para ter significado, para obter um momento específico na linha do tempo, você deve aplicar um fuso horário.LocalDateTime
vs.ZonedDateTime
vs.OffsetDateTime
vs.Instant
vs.LocalDate
vs.LocalTime
, como manter a calma sobre por que é tão complicado e como fazê-lo à direita no primeiro tiro.LocalDateTime
provavelmente teria sido nomeadoZonelessOffsetlessDateTime
.Respostas:
Data e hora da análise
Para criar um
LocalDateTime
objeto a partir de uma sequência, você pode usar oLocalDateTime.parse()
método estático . É preciso uma string e umDateTimeFormatter
como parâmetro. ADateTimeFormatter
é usado para especificar o padrão de data / hora.Formatando data e hora
Para criar uma string formatada para fora de um
LocalDateTime
objeto, você pode usar oformat()
métodoObserve que existem alguns formatos de data / hora comumente usados, predefinidos como constantes em
DateTimeFormatter
. Por exemplo: UsarDateTimeFormatter.ISO_DATE_TIME
para formatar aLocalDateTime
instância de cima resultaria na cadeia de caracteres"1986-04-08T12:30:00"
.Os métodos
parse()
eformat()
estão disponíveis para todos os objetos relacionados a data / hora (por exemplo,LocalDate
ouZonedDateTime
)fonte
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")
format()
a classe LocalDateTime em vez de na instância? Pelo menos, é o que eu fiz: eu confusoDateTime
comdateTime
no exemplo acima.Você também pode usar
LocalDate.parse()
ouLocalDateTime.parse()
em umString
sem fornecer-lo com um padrão, se oString
é em formato ISO-8601 .por exemplo,
Saída ,
e use
DateTimeFormatter
somente se você tiver que lidar com outros padrões de data.Por exemplo, no exemplo a seguir, dd MMM uuuu representa o dia do mês (dois dígitos), três letras do nome do mês (janeiro, fevereiro, março, ...) e um ano de quatro dígitos:
Resultado
lembre-se também de que o
DateTimeFormatter
objeto é bidirecional; ele pode analisar a entrada e formatar a saída.Resultado
(veja a lista completa de padrões para formatação e análise do DateFormatter )
fonte
2018-08-09 12:00:08
mas quando analiso, vejo aT
adição de uma que não preciso. Existe uma forma de fazer isso ?yyyy-MM-dd hh:mm:ss
para analisar e formatar. OT sempre será exibido no formato padrão (ISO-8061), mas você pode usar seus próprios padrões.As duas respostas acima explicam muito bem a pergunta sobre os padrões das cordas. No entanto, caso você esteja trabalhando com a ISO 8601, não há necessidade de se aplicar,
DateTimeFormatter
pois o LocalDateTime já está preparado para isso:Converter LocalDateTime em fuso horário ISO8601 String
Converter da string ISO8601 de volta para um LocalDateTime
fonte
A análise de uma string com data e hora em um determinado momento (Java chama de "
Instant
") é bastante complicada. O Java vem resolvendo isso em várias iterações. A mais recente,java.time
ejava.time.chrono
, cobre quase todas as necessidades (exceto dilatação do tempo :)).No entanto, essa complexidade traz muita confusão.
A chave para entender a análise de datas é:
Por que o Java tem tantas maneiras de analisar uma data
... e por que é o
LocalDateTime
,ZonedDateTime
et al. tão complicadoExistem fusos horários . Um fuso horário é basicamente uma "faixa" * [1] da superfície da Terra cujas autoridades seguem as mesmas regras de quando é que esse horário é compensado. Isso inclui regras de horário de verão.
Os fusos horários mudam ao longo do tempo em várias áreas, principalmente com base em quem conquista quem. E as regras de um fuso horário também mudam com o tempo .
Existem compensações de tempo. Isso não é o mesmo que fusos horários, porque um fuso horário pode ser, por exemplo, "Praga", mas com deslocamento de horário de verão e inverno.
Se você obtiver um registro de data e hora com um fuso horário, o deslocamento poderá variar, dependendo da parte do ano em que estiver. Durante a hora do salto, o registro de data e hora poderá significar 2 vezes diferentes, portanto, sem informações adicionais, não poderá ser confiável. convertido.
Nota: Por carimbo de data / hora, quero dizer "uma sequência que contém uma data e / ou hora, opcionalmente com um fuso horário e / ou deslocamento de hora".
Vários fusos horários podem compartilhar o mesmo deslocamento de tempo por determinados períodos. Por exemplo, o fuso horário GMT / UTC é igual ao fuso horário "Londres" quando o deslocamento da hora de verão não está em vigor.
Para tornar um pouco mais complicado (mas isso não é muito importante para o seu caso de uso):
2040-12-31 24:00:00
Pode ser uma data e hora válidas.) Isso precisa de atualizações regulares dos metadados que os sistemas usam para ter as conversões de data corretas. Por exemplo, no Linux, você recebe atualizações regulares dos pacotes Java, incluindo esses novos dados.As atualizações nem sempre mantêm o comportamento anterior para registros de data e hora históricos e futuros. Portanto, pode ser que a análise dos dois carimbos de data e hora em torno da alteração de algum fuso horário comparando-os possa fornecer resultados diferentes ao executar em versões diferentes do software. Isso também se aplica à comparação entre o fuso horário afetado e outro fuso horário.
Se isso causar um erro no seu software, considere usar algum registro de data e hora que não possua regras tão complicadas, como o registro de data e hora do UNIX .
Por causa do 7, para as datas futuras, não podemos converter datas exatamente com certeza. Assim, por exemplo, a análise atual
8524-02-17 12:00:00
pode demorar alguns segundos a partir da análise futura.As APIs do JDK para isso evoluíram com as necessidades contemporâneas
java.util.Date
tiveram uma abordagem um pouco ingênua, assumindo que há apenas o ano, mês, dia e hora. Isso rapidamente não foi suficiente.java.sql.Date
foram introduzidas, com suas próprias limitações.Calendar
API foi introduzida.Como lidar com isso em Java
java.time
Determine que tipo analisar um timestamp para
Quando você está consumindo uma sequência de carimbo de data e hora, precisa saber quais informações ela contém. Este é o ponto crucial. Se você não acertar, você terá exceções enigmáticas como "Não é possível criar instantâneo" ou "Falta o deslocamento da zona" ou "ID da zona desconhecida" etc.
Contém a data e a hora?
Tem um deslocamento de tempo?
Um deslocamento de tempo é a
+hh:mm
parte. Às vezes,+00:00
pode ser substituídoZ
por "horário do Zulu",UTC
como horário universal coordenado ouGMT
horário médio de Greenwich. Eles também definem o fuso horário.Para esses registros de data e hora, você usa
OffsetDateTime
.Tem um fuso horário?
Para esses registros de data e hora, você usa
ZonedDateTime
.A zona é especificada por
A lista de fusos horários é compilada por um "banco de dados TZ" , apoiado pelo ICAAN.
De acordo com
ZoneId
o javadoc, os IDs da zona também podem, de alguma forma, ser especificados comoZ
e deslocados. Não tenho certeza de como isso é mapeado para zonas reais. Se o registro de data e hora, que possui apenas um TZ, cai em uma hora bissexta da mudança de deslocamento de tempo, é ambíguo e a interpretação está sujeitaResolverStyle
, veja abaixo.Se não tiver nenhum , o contexto ausente será assumido ou negligenciado. E o consumidor tem que decidir. Portanto, ele precisa ser analisado
LocalDateTime
e convertido emOffsetDateTime
, adicionando as informações ausentes:Duration
), ou quando você não sabe e isso realmente não importa (por exemplo, horário do ônibus local).Informações de tempo parcial
LocalDate
,LocalTime
,OffsetTime
,MonthDay
,Year
, ouYearMonth
fora dele.Se você tiver todas as informações, poderá obter um
java.time.Instant
. Isso também é usado internamente para converter entreOffsetDateTime
eZonedDateTime
.Descobrir como analisá-lo
Existe uma extensa documentação na
DateTimeFormatter
qual é possível analisar uma string de carimbo de data e hora e formatar a string.Os s pré-criados
DateTimeFormatter
devem abranger todos os formatos padrão de registro de data e hora. Por exemplo,ISO_INSTANT
pode analisar2011-12-03T10:15:30.123457Z
.Se você tiver algum formato especial, poderá criar seu próprio DateTimeFormatter (que também é um analisador).
Eu recomendo olhar para o código fonte
DateTimeFormatter
e me inspirar em como criar um usandoDateTimeFormatterBuilder
. Enquanto estiver lá, verifique também oResolverStyle
que controla se o analisador é LENIENT, SMART ou STRICT para os formatos e informações ambíguas.TemporalAccessor
Agora, o erro frequente é entrar na complexidade de
TemporalAccessor
. Isso vem de como os desenvolvedores estavam acostumados a trabalharSimpleDateFormatter.parse(String)
. Certo,DateTimeFormatter.parse("...")
te dáTemporalAccessor
.Mas, equipado com o conhecimento da seção anterior, você pode analisar convenientemente o tipo que precisa:
Você realmente não precisa disso
DateTimeFormatter
. Os tipos que você deseja analisar têm osparse(String)
métodosEm relação a
TemporalAccessor
, você pode usá-lo se tiver uma vaga idéia de quais informações existem na string e deseja decidir em tempo de execução.Espero lançar alguma luz de entendimento em sua alma :)
Nota: Há um backport
java.time
para Java 6 e 7: ThreeTen-Backport . Para o Android, ele possui o ThreeTenABP .[1] Não apenas por não serem listras, mas também por alguns extremos estranhos. Por exemplo, algumas ilhas do Pacífico vizinhas têm fusos horários +14: 00 e -11: 00. Isso significa que, enquanto em uma ilha há 1 de maio às 15h, em outra ilha não tão longe, ainda é 30 de abril às 12h (se contei corretamente :))
fonte
OBTENHA A HORA UTC ATUAL NO FORMATO NECESSÁRIO
fonte
Achei maravilhoso cobrir várias variantes do formato de data e hora como este:
fonte