@Joachim O lado negativo dessa abordagem "padrão" é que eu tenho que ter muitas instâncias "yyyy-MM-dd'T'HH:mmZ"no meu aplicativo, sempre que precisar de uma data formatada ISO-8601. Com JodaTime, a meu ver, eu posso usar um formatador pré-definido ISODateTimeFormat, o que faz este trabalho para mim ..
yegor256
8
@Joachim, Zé padrão válido em SimpleDateFormat, em vez fazer isso: yyyy-MM-dd'T'HH:mm'Z'.
Buhake Sindi
33
-1 Isso fornece a data / hora no fuso horário atual - não no UTC. A resposta de Carlos inclui o código UTC necessário.
22812 Scott Rippey em
16
Acabei de corrigir o erro de fuso horário - já que é a resposta aceita, acho que foi a coisa certa a fazer.
BoD 16/08/13
2
O Z precisa ser citado como "aaaa-MM-dd'T'HH: mm'Z '"
Kimball Robinson
224
Para sistemas em que o fuso horário padrão não é UTC:
A SimpleDateFormatinstância pode ser declarada como uma constante global, se necessário com freqüência, mas tome cuidado para que essa classe não seja segura para threads. Ele deve ser sincronizado se acessado simultaneamente por vários encadeamentos.
EDIT: Eu preferiria Joda Time se estivesse fazendo muitas manipulações diferentes de Data / Hora ...
EDIT2: corrigido: setTimeZonenão aceita uma String (corrigida por Paul)
Esse formato não é uma constante em algum lugar da biblioteca integrada?
Daniel Kaplan
Existem dois pacotes diferentes para 'DateFormat', lembre-se de uso 'java.text.DateFormat importação'
oabarca
3
Se você deseja o fuso horário atual, use TimeZone tz = TimeZone.getDefault (); em vez
oabarca
Você não deve citar o 'Z' no formato, pois isso o torna logicamente insignificante. Se o fuso horário for UTC, como no exemplo acima, um Z não citado resultará apenas em um Z na saída ... no entanto, se o fuso horário não for UTC, o Z ainda será emitido como um UTC que implica literalmente quando o horário não for estar. Se um sistema consumidor ler o Z como UTC, mas a hora não for, a hora será alterada. Por outro lado, se um analisador usar o Z entre aspas sem definir o fuso horário, ele analisará os horários UTC como horários locais (novamente mudando). Essa cotação não é necessária se o TZ estiver definido, mas é perigoso se não estiver.
Matt Whipple
@MattWhipple - mas se você usar um Z unquoted o resultado será algo como 2016-06-14T13:56+0000- a questão está pedindo algo como2016-06-14T13:56Z
user85421
184
Java 8 Native
O java.time simplifica desde o Java 8. E é seguro para threads.
Você pode ficar tentado a usar isqueiros Temporalcomo Instantou LocalDateTime, mas não possui suporte ao formatador ou dados de fuso horário. Só ZonedDateTimefunciona fora da caixa.
Para Java 6 e 7, considere as portas traseiras do java.time, como o ThreeTen-Backport , que também possui uma porta Android . Ambos são mais leves que Joda e aprenderam com a experiência de Joda - esp. considerando que java.time foi desenvolvido pelo autor de Joda.
Boa resposta. Observe o bom hábito de especificar explicitamente um fuso horário em vez de confiar implicitamente no fuso horário atual da JVM. Você pode especificar um fuso horário específico, se desejar, como ZoneId.of( "America/Montreal" ).
Basil Bourque 17/02
1
O Instant permite formatá-lo no formato ISO 8601, basta chamar o método .toString ():return DateTimeFormatter.ISO_INSTANT.format(this);
VadymVL 7/17
Isso é melhor porque você evita o padrão.
Christophe Roussy
6
Aviso: A solução para Java 8 usando ISO_INSTANT possui uma peculiaridade irritante. Quando os milissegundos são 0, eles não são incluídos na saída. Isso é permitido de acordo com o padrão ISO 8601, mas muitas bibliotecas e analisadores em outros idiomas não perdoam. Se for necessário incluir sempre os zeros, use-o: DateTimeFormatter ISO_8601 = ofPattern ("aaaa-MM-dd'T'HH: mm: ss.SSSX"). WithZone (UTC);
22918 jurgen
Depois de mudar do Java 8 para o 11, vejo DateTimeFormatter.ISO_INSTANTe DateTimeFormatter.ISO_DATE_TIMEuso 6 dígitos após os segundos, em oposição a 3, que não são mais capturados pelo Spring @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME).
Bem, você inclui uma biblioteca extra de terceiros como uma dependência do seu projeto (que você pode manter atualizado e envia com seu aplicativo, ei, são apenas 3,2 megabytes extras) e faz DateTime dt = new DateTime(); DateTimeFormatter fmt = ISODateTimeFormat.dateTime(); String str = fmt.print(dt);, ou encapsula return String.format("%tFT%<tRZ", new Date());em uma classe e faça str = Iso8601Time.now(), sempre que precisar. (Não é como se o formato ISO fosse alterado.) Se você precisar de mais do que apenas a data atual no formato ISO, use uma lib.
aioobe
2
Concordo totalmente com isso.
yegor256
3
Observe que é possível alterar qual resposta está marcada como aceita ;-) #
Esta é a resposta certa, e é um escândalo que ela não tenha sido votada mais alto por todas essas coisas inventadas SimpleDateFormats.
David Moles
Ainda bem que li mais respostas. Eu concordo, esta deve ser a resposta agora.
Xan-Kun Clark-Davis
E porque é toString, em muitos casos, você nem precisará chamá-lo explicitamente.
kaya3 25/02
1
O aviso em um comentário em uma resposta anterior também se aplica aqui: "Aviso: A solução para Java 8 usando ISO_INSTANT tem uma peculiaridade irritante. Quando os milissegundos são 0, eles não são incluídos na saída. Isso é permitido de acordo com a ISO 8601 padrão, mas muitas bibliotecas e analisadores em outros idiomas não perdoam ".
Se você não deseja adicionar ou não vê o valor de adicionar a biblioteca acima, basta usar a SimpleDateFormatclasse construída para formatar a Data no formato ISO exigido
E como você produziria uma String formatada como mostrado na pergunta?
Joachim Sauer
4
Eu diria que não adicione uma dependência de biblioteca para algo tão simples como este (que pode ser alcançado com duas linhas de código java). (Claro, se as exigências cresce, é outra história.)
aioobe
1
@aioobe, se é apenas usado em várias partes do aplicativo, então está ok para ir para o padrão, no resto, o caso jodatime é melhor.
Jigar Joshi
5
O @aioobe jodatime é melhor em qualquer caso, porque possui ISODateTimeFormat- um formatador predefinido da ISO-8601.
yegor256
3
@ org.life.java: que são relevantes apenas quando você pode alternar para a hora do Jode corretamente. Você não os terá quando usar apenas esta função do tempo Joda.
Joachim Sauer
20
DateFormatUtils do Apache commons-lang3tem constantes úteis, por exemplo:DateFormatUtils.ISO_DATETIME_FORMAT
Mais precisamente, o momento atual em UTC: DateFormatUtils.format(new Date(), "yyyy-MM-dd'T'HH:mm'Z'", TimeZone.getTimeZone("UTC"));momento atual no fuso horário padrão: DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(new Date()); @ yegor256 obrigado por mencionar DateFormatUtils, ter a bordo do apache commons-lang vale a pena usar o formato da data.
babinik
19
Se você não deseja incluir o Jodatime (por mais legal que seja)
Isso é seguro para threads. O Joda-Time cria novos objetos imutáveis, em vez de alterar os objetos existentes.
Se você realmente pretendia solicitar um formato sem segundos, resolvendo para minutos, use um dos muitos outros formatadores incorporados no Joda-Time.
DateTime now =newDateTime(DateTimeZone.UTC );String output =ISODateTimeFormat.dateHourMinute.print( now );
java.time
Para Java 8 e posterior, o Joda-Time continua funcionando. Mas a estrutura java.time integrada substitui o Joda-Time. Portanto, migre seu código do Joda-Time para java.time assim que for conveniente.
Para saber mais, consulte o Tutorial do Oracle . E procure Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .
Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de java.sql.*classes.
O projeto ThreeTen-Extra estende java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como Interval, YearWeek, YearQuarter, e mais .
Você pode usar o SimpleDateFormat do Java com o seguinte padrão yyyy-MM-dd'T'HH:mm:ssXXXpara ISO 8601.
Código de exemplo: (lista todos os fusos horários disponíveis)
for(String timeZone :TimeZone.getAvailableIDs()){DateFormat dateFormat =newSimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
dateFormat.setTimeZone(TimeZone.getTimeZone(timeZone));String formatted = dateFormat.format(newDate());System.out.print(formatted);if(formatted.endsWith("Z")){// These time zone's have offset of '0' from GMT.System.out.print("\t("+ timeZone +")");}System.out.println();}
Se você deseja a hora atual, não há necessidade de passar por um Dateobjeto antiquado . Apenas faça Instant.now().toString(). Se você recebeu uma DateAPI herdada, seu método é o melhor.
Algumas das outras respostas estão corretas ao recomendar as classes java.time , mas continuam usando comprimentos desnecessários para suas necessidades específicas.
Instant.now()// Capture the current moment in UTC with a resolution as fines nanoseconds but usually in microseconds or milliseconds..truncatedTo(ChronoUnit.MINUTES )// Lop off any seconds or fractional second, to get a value in whole minutes..toString()// Generate a String in standard ISO 8601 format where a `T` separates the year-month-day from the hour-minute-second, and the `Z` on the end for “Zulu” means UTC.
2018-01-23T12: 34Z
Instant::toString
A jav.time.Instantclasse representa um momento no UTC, sempre no UTC.
Instant instant =Instant.now();
Instale o Adobe Flash Player no seu dispositivo
O Zfinal de sua sequência de exemplo 2010-10-12T08:50Zé pronunciado "Zulu" e significa UTC .
O formato desejado está em conformidade com a norma ISO 8601 . As classes java.time usam esses formatos padrão por padrão ao analisar / gerar strings. Portanto, não há necessidade de especificar um padrão de formatação. Basta ligar Instant::toStringcomo visto acima.
Se você deseja especificamente minutos inteiros sem segundo ou segundo fracionário, então trunque. Especifique uma unidade de tempo via ChronoUnitclasse.
Instant instant =Instant.now().truncatedTo(ChronoUnit.MINUTES );String output = instant.toString();// Generate a `String` object in standard ISO 8601 format.
Para saber mais, consulte o Tutorial do Oracle . E procure Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .
Você pode trocar java.time objetos diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de java.sql.*classes.
O projeto ThreeTen-Extra estende java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como Interval, YearWeek, YearQuarter, e mais .
Torná-lo estático pode causar problemas, já que SimpleDateFormat não é seguro para threads: "Os formatos de data não são sincronizados. É recomendável criar instâncias de formato separadas para cada thread. Se vários threads acessarem um formato simultaneamente, ele deverá ser sincronizado externamente." docs.oracle.com/javase/7/docs/api/java/text/…
Juha Palomäki
2
Como @Juha Palomäki mencionou, isso não é seguro. Se você estiver usando o Java 8 ou superior, o ThreadLocal.withInitial poderá corrigir isso. Se você estiver usando o Java 7 ou inferior, crie um novo ThreadLocal e forneça um valor inicial substituindo ThreadLocal.initialValue
user393274
@ user393274 - se você estiver usando Java 8 você deve usar Instant, DateTimeFormate os outros moderna rosca substituições seguras
Estou um pouco confuso com o problema de SimpleDateFormat não ser seguro para threads. Se dois threads executam o inicializador estático ao mesmo tempo, não vejo nada pior acontecendo do que o construtor SimpleDateFormat é chamado duas vezes, mas apenas um instante (o último a terminar) é registrado como "df".
gilbertpilz
2
privatestaticString getCurrentDateIso(){// Returns the current date with the same format as Javascript's new Date().toJSON(), ISO 8601DateFormat dateFormat =newSimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));return dateFormat.format(newDate());}
Ainda assim, o joda-time suporta apenas o formato estendido: "2015-12-09T00: 22: 42.930Z", não o básico: "20151209T002242.930Z" ... talvez seja melhor testar uma lista de formatos com o java SimpleDateFormat.
Eu fiz isso no Android usando o Calendar e SimpleDateFormat. O método a seguir retorna um calendário com o fuso horário "GMT" (este é o fuso horário universal). Em seguida, você pode usar a classe Calendar para definir a hora entre diferentes fusos horários, usando o método setTimeZone () da classe Calendar.
LEMBRE-SE: A classe Date não sabe sobre a existência do fuso horário. Por esse motivo, se você depurar uma data, sempre verá a data do seu fuso horário atual.
Se você se preocupa com o desempenho, criei uma biblioteca que supera o analisador e o formatador Java padrão ao manipular com datas no formato ISO8601. As implementações do DatetimeProcessor são seguras para encadeamento e podem ser armazenadas em cache em um mapa simultâneo ou em campos estáticos.
Eles deveriam ter adicionado algum tipo de maneira simples de ir do Date para o Instant e também um método chamado toISO8601, que é o que muitas pessoas procuram. Como complemento para outras respostas, do formato java.util.Date para ISO 8601:
Instant.ofEpochMilli(date.getTime()).toString();
Não é realmente visível ao usar o preenchimento automático, mas
java.time.Instant.toString():
Uma representação em cadeia deste instante usando ISO-8601
Embora esse código possa responder à pergunta, fornecer um contexto adicional sobre por que e / ou como esse código responde à pergunta melhora seu valor a longo prazo.
private static SimpleDateFormat
não é seguro para threads.Respostas:
Use
SimpleDateFormat
para formatar qualquerDate
objeto que você deseja:Usar um
new Date()
como mostrado acima formatará a hora atual.fonte
"yyyy-MM-dd'T'HH:mmZ"
no meu aplicativo, sempre que precisar de uma data formatada ISO-8601. Com JodaTime, a meu ver, eu posso usar um formatador pré-definidoISODateTimeFormat
, o que faz este trabalho para mim ..Z
é padrão válido em SimpleDateFormat, em vez fazer isso:yyyy-MM-dd'T'HH:mm'Z'
.Para sistemas em que o fuso horário padrão não é UTC:
A
SimpleDateFormat
instância pode ser declarada como uma constante global, se necessário com freqüência, mas tome cuidado para que essa classe não seja segura para threads. Ele deve ser sincronizado se acessado simultaneamente por vários encadeamentos.EDIT: Eu preferiria Joda Time se estivesse fazendo muitas manipulações diferentes de Data / Hora ...
EDIT2: corrigido:
setTimeZone
não aceita uma String (corrigida por Paul)fonte
2016-06-14T13:56+0000
- a questão está pedindo algo como2016-06-14T13:56Z
Java 8 Native
O java.time simplifica desde o Java 8. E é seguro para threads.
Resultado:
2015-04-14T11:07:36.639Z
Ao ajustar ou encadear as opções / operações de ZonedDateTime e DateTimeFormatter , você pode controlar facilmente o fuso horário e a precisão , até um certo grau:
Resultado:
2015-04-14T11:07:00+01:00[Europe/Paris]
Requisitos refinados, como a remoção da parte dos segundos, ainda devem ser atendidos por formatos personalizados ou pós-processamento personalizado.
fonte
ZoneId.of( "America/Montreal" )
.return DateTimeFormatter.ISO_INSTANT.format(this);
DateTimeFormatter.ISO_INSTANT
eDateTimeFormatter.ISO_DATE_TIME
uso 6 dígitos após os segundos, em oposição a 3, que não são mais capturados pelo Spring@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
.Java 8:
Antes do Java 8:
Dos documentos :
fonte
DateTime dt = new DateTime(); DateTimeFormatter fmt = ISODateTimeFormat.dateTime(); String str = fmt.print(dt);
, ou encapsulareturn String.format("%tFT%<tRZ", new Date());
em uma classe e façastr = Iso8601Time.now()
, sempre que precisar. (Não é como se o formato ISO fosse alterado.) Se você precisar de mais do que apenas a data atual no formato ISO, use uma lib.%tFT%<tTZ
incluirá segundos;%tFT%<tTZ.%<tL
incluirá milissegundos.No Java 8, você pode simplesmente fazer:
Dos
java.time.Instant
documentos:fonte
SimpleDateFormats
.toString
, em muitos casos, você nem precisará chamá-lo explicitamente.use JodaTime
Aqui está o documento para o JodaTime Formatter
Editar:
Se você não deseja adicionar ou não vê o valor de adicionar a biblioteca acima, basta usar a
SimpleDateFormat
classe construída para formatar a Data no formato ISO exigidocomo sugerido por @Joachim Sauer
fonte
ISODateTimeFormat
- um formatador predefinido da ISO-8601.DateFormatUtils do Apache
commons-lang3
tem constantes úteis, por exemplo:DateFormatUtils.ISO_DATETIME_FORMAT
fonte
DateFormatUtils.format(new Date(), "yyyy-MM-dd'T'HH:mm'Z'", TimeZone.getTimeZone("UTC"));
momento atual no fuso horário padrão:DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(new Date())
; @ yegor256 obrigado por mencionarDateFormatUtils
, ter a bordo do apache commons-lang vale a pena usar o formato da data.Se você não deseja incluir o Jodatime (por mais legal que seja)
que retorna uma sequência de:
que é um pouco diferente da solicitação original, mas ainda é ISO-8601.
fonte
A ISO 8601 pode conter segundos, consulte http://en.wikipedia.org/wiki/ISO_8601#Times
então o código deve ser
fonte
Joda-Time
Atualização: o projeto Joda-Time agora está no modo de manutenção , com a equipe aconselhando a migração para as classes java.time . Para Java 6 e 7, consulte o projeto ThreeTen-Backport , mais adaptado para Android no projeto ThreeTenABP .
Usando a biblioteca Joda-Time …
Isso é seguro para threads. O Joda-Time cria novos objetos imutáveis, em vez de alterar os objetos existentes.
Se você realmente pretendia solicitar um formato sem segundos, resolvendo para minutos, use um dos muitos outros formatadores incorporados no Joda-Time.
java.time
Para Java 8 e posterior, o Joda-Time continua funcionando. Mas a estrutura java.time integrada substitui o Joda-Time. Portanto, migre seu código do Joda-Time para java.time assim que for conveniente.
Veja minha outra resposta para uma solução moderna.
Sobre java.time
A estrutura java.time é integrada ao Java 8 e posterior. Essas classes suplantar os velhos problemáticos legados aulas de data e hora, como
java.util.Date
,Calendar
, eSimpleDateFormat
.O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para as classes java.time .
Para saber mais, consulte o Tutorial do Oracle . E procure Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .
Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de
java.sql.*
classes.Onde obter as classes java.time?
O projeto ThreeTen-Extra estende java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como
Interval
,YearWeek
,YearQuarter
, e mais .fonte
Para Java versão 7
Você pode seguir a documentação do Oracle: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
X - é usado para o fuso horário ISO 8601
fonte
Você pode usar o SimpleDateFormat do Java com o seguinte padrão
yyyy-MM-dd'T'HH:mm:ssXXX
para ISO 8601.Você poderia usar:
para o fuso horário padrão da vm. Mais aqui
Você pode observar a data e hora de alguns fusos horários que terminam com
'Z'
. Esses fusos horários foram deslocados em'0'
relação ao GMT.Mais informações podem ser encontradas aqui .
fonte
Eu acredito que a maneira mais fácil é primeiro ir para o instante e depois para string como:
O que resultará em:
2017-09-08T12:56:45.331Z
fonte
Date
objeto antiquado . Apenas façaInstant.now().toString()
. Se você recebeu umaDate
API herdada, seu método é o melhor.java.util.Date
,java.util.Calendar
, ejava.text.SimpleDateFormat
são agora legado , suplantado pelo java.time classes internas em Java 8 e posterior. Vejo Tutorial da Oracle .tl; dr
Algumas das outras respostas estão corretas ao recomendar as classes java.time , mas continuam usando comprimentos desnecessários para suas necessidades específicas.
Instant::toString
A
jav.time.Instant
classe representa um momento no UTC, sempre no UTC.O
Z
final de sua sequência de exemplo2010-10-12T08:50Z
é pronunciado "Zulu" e significa UTC .O formato desejado está em conformidade com a norma ISO 8601 . As classes java.time usam esses formatos padrão por padrão ao analisar / gerar strings. Portanto, não há necessidade de especificar um padrão de formatação. Basta ligar
Instant::toString
como visto acima.Se você deseja especificamente minutos inteiros sem segundo ou segundo fracionário, então trunque. Especifique uma unidade de tempo via
ChronoUnit
classe.Sobre java.time
A estrutura java.time é integrada ao Java 8 e posterior. Essas classes substituem o antigo e problemático legado data e hora , como
java.util.Date
,Calendar
, eSimpleDateFormat
.o Jodaprojeto , agora em modo de manutenção , aconselha a migração para as classes java.time .
Para saber mais, consulte o Tutorial do Oracle . E procure Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .
Você pode trocar java.time objetos diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de
java.sql.*
classes.Onde obter as classes java.time?
O projeto ThreeTen-Extra estende java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como
Interval
,YearWeek
,YearQuarter
, e mais .fonte
Aqui está uma classe inteira otimizada para que invocar "now ()" não faça mais do que precisa.
fonte
Instant
,DateTimeFormat
e os outros moderna rosca substituições segurasfonte
Ainda assim, o joda-time suporta apenas o formato estendido: "2015-12-09T00: 22: 42.930Z", não o básico: "20151209T002242.930Z" ... talvez seja melhor testar uma lista de formatos com o java SimpleDateFormat.
fonte
Eu fiz isso no Android usando o Calendar e SimpleDateFormat. O método a seguir retorna um calendário com o fuso horário "GMT" (este é o fuso horário universal). Em seguida, você pode usar a classe Calendar para definir a hora entre diferentes fusos horários, usando o método setTimeZone () da classe Calendar.
LEMBRE-SE: A classe Date não sabe sobre a existência do fuso horário. Por esse motivo, se você depurar uma data, sempre verá a data do seu fuso horário atual.
fonte
Se você se preocupa com o desempenho, criei uma biblioteca que supera o analisador e o formatador Java padrão ao manipular com datas no formato ISO8601. As implementações do DatetimeProcessor são seguras para encadeamento e podem ser armazenadas em cache em um mapa simultâneo ou em campos estáticos.
fonte
Eles deveriam ter adicionado algum tipo de maneira simples de ir do Date para o Instant e também um método chamado
toISO8601
, que é o que muitas pessoas procuram. Como complemento para outras respostas, do formato java.util.Date para ISO 8601:Não é realmente visível ao usar o preenchimento automático, mas
java.time.Instant.toString()
:fonte
fonte
Experimente,
É para o formato ISO 8601
fonte