Como obter o momento atual no formato ISO 8601 com data, hora e minuto?

Qual é a maneira mais elegante de obter a apresentação formatada ISO 8601 do momento atual, UTC? Deve se parecer com: 2010-10-12T08:50Z .

Use SimpleDateFormat para formatar qualquer object Date desejado:

 TimeZone tz = TimeZone.getTimeZone("UTC"); DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); // Quoted "Z" to indicate UTC, no timezone offset df.setTimeZone(tz); String nowAsISO = df.format(new Date()); 

Usando uma new Date() como mostrado acima irá formatar a hora atual.

Para sistemas em que o fuso horário padrão não é UTC:

 TimeZone tz = TimeZone.getTimeZone("UTC"); DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); df.setTimeZone(tz); String nowAsISO = df.format(new Date()); 

A instância SimpleDateFormat pode ser declarada como uma constante global, se necessário, com frequência, mas tenha cuidado com o fato de essa class não ser thread-safe. Ele deve ser sincronizado se acessado simultaneamente por vários encadeamentos.

EDIT: Eu preferiria Joda Time se fazendo muitas manipulações diferentes de Times / Date …
EDIT2: corrigido: setTimeZone não aceita uma String (corrigida por Paul)

Java 8:

 thisMoment = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmX") .withZone(ZoneOffset.UTC) .format(Instant.now()); 

Pré Java 8:

 thisMoment = String.format("%tFT% 

Dos docs :

'R' Tempo formatado para o relógio de 24 horas como "% tH:% tM"
Data completa do 'F' ISO 8601 formatada como "% tY-% tm-% td".

Java 8 nativo

java.time torna simples desde o Java 8. E thread safe.

 ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_INSTANT ) 

Resultado: 2015-04-14T11:07:36.639Z

Você pode ficar tentado a usar Temporal mais leve, como Instant ou LocalDateTime , mas eles não têm suporte ao formatador ou dados de fuso horário. Apenas ZonedDateTime funciona fora da checkbox.

Ao ajustar ou encadear as opções / operações de ZonedDateTime e DateTimeFormatter , você pode facilmente controlar o fuso horário e a precisão , até certo ponto:

 ZonedDateTime.now( ZoneId.of( "Europe/Paris" ) ) .truncatedTo( ChronoUnit.MINUTES ) .format( DateTimeFormatter.ISO_DATE_TIME ) 

Resultado: 2015-04-14T11:07:00+01:00[Europe/Paris]

Requisitos refinados, como a remoção da parte de segundos, ainda devem ser atendidos por formatos personalizados ou por processos de postagem personalizados.

 .format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // 2015-04-14T11:07:00 .format( DateTimeFormatter.ISO_LOCAL_DATE ) // 2015-04-14 .format( DateTimeFormatter.ISO_LOCAL_TIME ) // 11:07:00 .format( DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm" ) ) // 2015-04-14 11:07 

Para o Java 6 e 7, você pode considerar back-ports do java.time, como o ThreeTen-Backport , que também tem uma porta do Android . Ambos são mais leves que Joda e aprenderam com a experiência de Joda – esp. considerando que java.time é projetado pelo autor de Joda.

use JodaTime

O sistema de calendar ISO 8601 é a implementação padrão dentro do Joda-Time

Aqui está o doc para JodaTime Formatter

Editar:

Se você não quer adicionar ou se você não vê o valor de adicionar a biblioteca acima, você poderia simplesmente usar a class SimpleDateFormat para formatar a Data no formato ISO requerido.

como sugerido por @Joachim Sauer

 DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ"); String nowAsString = df.format(new Date()); 

A partir do Java 8, você pode simplesmente fazer:

 Instant.now().toString(); 

Dos documentos java.time.Instant :

agora


public static Instant now()

Obtém o instante atual do relógio do sistema.

Isto irá consultar o relógio UTC do sistema para obter o instante atual.

para sequenciar


public String toString()

Uma representação de string deste instante usando a representação ISO-8601.

O formato usado é o mesmo que DateTimeFormatter.ISO_INSTANT .

DateFormatUtils do Apache commons-lang3 têm constantes úteis, por exemplo: DateFormatUtils.ISO_DATETIME_FORMAT

Se você não quer include Jodatime (por mais legal que seja)

 javax.xml.bind.DatatypeConverter.printDateTime( Calendar.getInstance(TimeZone.getTimeZone("UTC")) ); 

que retorna uma string de:

 2012-07-10T16:02:48.440Z 

que é um pouco diferente da solicitação original, mas ainda é ISO-8601.

ISO 8601 pode conter segundos, consulte http://en.wikipedia.org/wiki/ISO_8601#Times

então o código deve ser

 DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 

Joda-Time

Atualização: O projeto Joda-Time está agora no modo de manutenção , com a equipe aconselhando a migration para as classs java.time . Para o Java 6 e 7, consulte o projeto ThreeTen-Backport , adaptado para o Android no projeto ThreeTenABP .

Usando a biblioteca Joda-Time …

 String output = new DateTime( DateTimeZone.UTC ).toString() ; 

Isso é seguro para thread. O Joda-Time cria novos objects imutáveis ​​em vez de alterar os objects existentes.

Se você realmente pretendia pedir um formato sem segundos, resolvendo em minutos, então use um dos muitos outros formatadores embutidos no Joda-Time.

 DateTime now = new DateTime( DateTimeZone.UTC ) ; String output = ISODateTimeFormat.dateHourMinute.print( now ) ; 

java.time

Para o Java 8 e posterior, o Joda-Time continua a funcionar. Mas o framework java.time incorporado suplanta o Joda-Time. Então, migre seu código do Joda-Time para o java.time assim que for conveniente.

Veja minha outra resposta para uma solução moderna.


Sobre o java.time

O framework java.time está embutido no Java 8 e posterior. Essas classs substituem as antigas classs herdadas de data e hora legadas , como java.util.Date , Calendar e SimpleDateFormat .

O projeto Joda-Time , agora em modo de manutenção , aconselha a migration para as classs java.time .

Para saber mais, veja o Oracle Tutorial . E pesquise o Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .

Você pode trocar objects java.time diretamente com seu database. Use um driver JDBC compatível com o JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de classs java.sql.* .

Onde obter as classs java.time?

  • Java SE 8 , Java SE 9 , Java SE 10 e posterior
    • Construídas em.
    • Parte da API Java padrão com uma implementação integrada.
    • O Java 9 adiciona alguns resources e correções menores.
  • Java SE 6 e Java SE 7
    • Grande parte da funcionalidade java.time é transferida para o Java 6 e 7 no ThreeTen-Backport .
  • Android
    • Versões posteriores das implementações do pacote Android das classs java.time.
    • Para Android anterior (<26), o projeto ThreeTenABP adapta o ThreeTen-Backport (mencionado acima). Veja Como usar o ThreeTenABP… .

O projeto ThreeTen-Extra estende java.time com classs adicionais. Este projeto é um campo de testes para possíveis futuras adições ao java.time. Você pode encontrar algumas classs úteis aqui como Interval , YearWeek , YearQuarter e muito mais .

Para o 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

 TimeZone tz = TimeZone.getTimeZone("UTC"); DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"); df.setTimeZone(tz); String nowAsISO = df.format(new Date()); System.out.println(nowAsISO); DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"); //nowAsISO = "2013-05-31T00:00:00Z"; Date finalResult = df1.parse(nowAsISO); System.out.println(finalResult); 

Você pode usar o SimpleDateFormat do Java com o seguinte padrão yyyy-MM-dd'T'HH:mm:ssXXX para ISO 8601.

Exemplo de código: (lista para todos os fusos horários disponíveis)

 for (String timeZone : TimeZone.getAvailableIDs()) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); dateFormat.setTimeZone(TimeZone.getTimeZone(timeZone)); String formatted = dateFormat.format(new Date()); 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(); } 

Você poderia usar:

TimeZone.getDefault ()

para o fuso horário vm padrão. Mais aqui

Você pode notar a data e hora de alguns fusos horários que terminam com 'Z' . Esses fusos horários têm o deslocamento de '0' do GMT.

Mais informações podem ser encontradas aqui .

Eu acredito que a maneira mais fácil é ir primeiro para instant e depois para string como:

 String d = new Date().toInstant().toString(); 

Que resultará em:

2017-09-08T12:56:45.331Z

Aqui está uma class inteira otimizada para que invocar “now ()” não faça mais nada do que isso.

 public class Iso8601Util { private static TimeZone tz = TimeZone.getTimeZone("UTC"); private static DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); static { df.setTimeZone(tz); } public static String now() { return df.format(new Date()); } } 

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 no Android usando o Calendar e o SimpleDateFormat. O método a seguir retorna um calendar com o fuso horário “GMT” (este é o fuso horário universal). Em seguida, você pode usar a class Calendar para definir a hora entre fusos horários diferentes, usando o método setTimeZone () da class Calendar.

 private static final String GMT = "GMT"; private static final String DATE_FORMAT_ISO = "yyyyMMdd'T'HHmmss"; public static Calendar isoToCalendar(final String inputDate) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(GMT)); try { SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_ISO, Locale.US); dateFormat.setTimeZone(TimeZone.getTimeZone(GMT)); Date date = dateFormat.parse(inputDate); calendar.setTime(date); } catch (ParseException e) { Log.e("TAG",e.getMessage()); } return calendar; } 

LEMBRE-SE: A class Date não sabe sobre a existência do fuso horário. Por esse motivo, se você depurar uma data, verá sempre a data do fuso horário atual.

 private static String getCurrentDateIso() { // Returns the current date with the same format as Javascript's new Date().toJSON(), ISO 8601 DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); return dateFormat.format(new Date()); } 

Eles devem ter acrescentado algum tipo de maneira simples de ir de data para instantânea e também um método chamado toISO8601 , que é o que muita gente está procurando. Como complemento a outras respostas, de um formato java.util.Date para o formato 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 de string deste instante usando ISO-8601

tl; dr

Algumas das outras respostas estão corretas ao recomendar classs java.time , mas usam 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 class jav.time.Instant representa um momento no UTC, sempre em UTC.

 Instant instant = Instant.now() ; 

instant.toString (): 2018-01-23T12: 34: 56.123456Z

O Z no final do seu exemplo string 2010-10-12T08:50Z é pronunciado “Zulu” e significa UTC .

Seu formato desejado está em conformidade com a norma ISO 8601 . As classs java.time usam esses formatos padrão por padrão ao analisar / gerar cadeias. Portanto, não há necessidade de especificar um padrão de formatação. Apenas chame Instant::toString como visto acima.

Se você deseja especificamente minutos inteiros sem segundo ou segundo fracionário, trunque. Especifique uma unidade de tempo por ChronoUnit class ChronoUnit .

 Instant instant = Instant.now().truncatedTo( ChronoUnit.MINUTES ) ; String output = instant.toString(); // Generate a `String` object in standard ISO 8601 format. 

Sobre o java.time

O framework java.time está embutido no Java 8 e posterior. Essas classs substituem as antigas classs herdadas de data e hora legadas , como java.util.Date , Calendar e SimpleDateFormat .

O projeto Joda-Time , agora em modo de manutenção , aconselha a migration para as classs java.time .

Para saber mais, veja o Oracle Tutorial . E pesquise o Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .

Você pode trocar objects java.time diretamente com seu database. Use um driver JDBC compatível com o JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de classs java.sql.* .

Onde obter as classs java.time?

  • Java SE 8 , Java SE 9 , Java SE 10 e posterior
    • Construídas em.
    • Parte da API Java padrão com uma implementação integrada.
    • O Java 9 adiciona alguns resources e correções menores.
  • Java SE 6 e Java SE 7
    • Grande parte da funcionalidade java.time é transferida para o Java 6 e 7 no ThreeTen-Backport .
  • Android
    • Versões posteriores das implementações do pacote Android das classs java.time.
    • Para Android anterior (<26), o projeto ThreeTenABP adapta o ThreeTen-Backport (mencionado acima). Veja Como usar o ThreeTenABP… .

O projeto ThreeTen-Extra estende java.time com classs adicionais. Este projeto é um campo de testes para possíveis futuras adições ao java.time. Você pode encontrar algumas classs úteis aqui como Interval , YearWeek , YearQuarter e muito mais .

 DateTimeFormatter.ISO_DATE_TIME .withZone(ZoneOffset.UTC) .format(yourDateObject.toInstant()) 

Tente isso,

 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ"); String date=sdf.format (new Date() ); 

É para o formato ISO 8601