Java SimpleDateFormat (“aaaa-MM-dd'T'HH: mm: ss'Z '”) fornece o fuso horário como IST

148

Eu tenho o construtor SimpleDateFormat como

SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")

e eu estou analisando string "2013-09-29T18:46:19Z".

Eu li que aqui Z representa o GMT/UTCfuso horário. mas quando imprimo esta data no console, imprime o fuso horário IST para a data retornada.

Agora, minha pergunta é se minha saída está certa ou errada?

Pradip Borde
fonte
3
sim, é isso que 'Z' representa. Z- Fuso Horário
Woody
5
Z = Zulu time => GMT + 0, você obviamente não servem o seu país;)
MushyPeas

Respostas:

250

Você não definiu o fuso horário apenas para adicionar uma Zdata / hora ao final da data / hora; portanto, ela parecerá uma data / hora GMT, mas isso não altera o valor.

Defina o fuso horário como GMT e ele estará correto.

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
Peter Lawrey
fonte
3
Se você tem uma data, diga 2012-12-06T06: 00: 00 sem o Z, isso representa GMT?
Binarygiant #
3
@binarygiant Você teria que perguntar a quem o enviou. Pode ser a hora local do remetente.
Peter Lawrey
2
O fuso horário pode ser definido como "UTC"
Prashanth 30/06
2
Em vez de definir o fuso horário em tantos lugares para bibliotecas diferentes e evitar conflitos com o fuso horário da sua máquina / laptop, você sempre deve definir o fuso horário padrão da JVM configurando a propriedade do sistema user.timezone: java -Duser.timezone = GMT ...
Kisna
100

'T'e 'Z'são considerados aqui como constantes. Você precisa passar Zsem as aspas. Além disso, você precisa especificar o fuso horário na sequência de entrada.

Exemplo: 2013-09-29T18:46:19-0700 E o formato como"yyyy-MM-dd'T'HH:mm:ssZ"

Subir Kumar Sao
fonte
Subir, Obrigado pela sua resposta, mas o que é "0700" anexado à string de entrada?
Pradip Borde
-0700é o fuso horário, ou seja, -7: 00 Hrs
Subir Kumar Sao
12
para -07: 00 horas e não -0700, seria o seguinte: aaaa-MM-dd'T'HH: mm: ss.SSSXXX
Tastybrownies
48

De ISO 8601 String para Java Date Object

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf.parse("2013-09-29T18:46:19Z"); //prints-> Mon Sep 30 02:46:19 CST 2013

se você não definir TimeZone.getTimeZone("GMT"), ele exibiráSun Sep 29 18:46:19 CST 2013

Do objeto de data do Java para a sequência ISO 8601

E para converter um Dateobjeto no padrão ISO 8601 ( yyyy-MM-dd'T'HH:mm:ss'Z'), use o seguinte código

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));           
System.out.println(sdf.format(new Date())); //-prints-> 2015-01-22T03:23:26Z

Observe também que sem as impressões ' 'em Zyyyy-MM-dd'T'HH:mm:ssZ2015-01-22T03:41:02+0000

AZ_
fonte
2
Dá-me java.text.ParseException: data imperceptível: "2018-05-01T18: 30: 00.000Z" @AZ_
Mansuu ...
41

SE você deseja manipular ' padrão representação' JSON da data então é melhor usar este padrão: "yyyy-MM-dd'T'HH:mm:ssX".

Observe o Xno final. Ele manipulará fusos horários no padrão ISO 8601 e o ISO 8601 é exatamente o que produz essa declaração em Javascript.new Date().toJSON()

Comparando com outras respostas, tem alguns benefícios:

  1. Você não precisa exigir que seus clientes enviem a data no GMT
  2. Você não precisa converter explicitamente seu objeto Date para GMT usando este: sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
MyTitle
fonte
1
Estou usando playa vinculação automática de formulários e uso @Format.DateTimeanotações. O uso do padrão padrão com Zfinal parece estar incorreto. Depois de alterado para X, ele funciona. Muito obrigado
transang
Se sua data especificar o fuso horário de uma forma compatível com RFC822 como "-0500", isso funcionará bem. Mas para uma data como "2013-07-15T10: 22: 17-05: 00" (também ISO8601 TZ válido), isso ocorre. Nesse caso, você precisa usar "aaaa-MM-dd'T'HH: mm: ssXXX".
precisa
23

tl; dr

As outras respostas estão obsoletas no Java 8.

Instant                           // Represent a moment in UTC. 
.parse( "2013-09-29T18:46:19Z" )  // Parse text in standard ISO 8601 format where the `Z` means UTC, pronounces “Zulu”.
.atZone(                          // Adjust from UTC to a time zone. 
    ZoneId.of( "Asia/Kolkata" )
)                                 // Returns a `ZonedDateTime` object. 

ISO 8601

Por acaso, seu formato de string está em conformidade com o padrão ISO 8601 . Esse padrão define formatos sensíveis para representar vários valores de data e hora como texto.

java.time

As classes old java.util.Date/ .Calendarand java.text.SimpleDateFormatforam substituídas pela estrutura java.time incorporada no Java 8 e posterior. Veja o tutorial . Evite as classes antigas, pois elas provaram ser mal projetadas, confusas e problemáticas.

Parte do design inadequado das classes antigas o mordeu, onde o toStringmétodo aplica o fuso horário atual da JVM ao gerar uma representação de texto do valor de data e hora que está realmente no UTC (GMT); bem-intencionado, mas confuso.

As classes java.time usam os formatos ISO 8601 por padrão ao analisar / gerar representações textuais de valores de data e hora. Portanto, não há necessidade de especificar um padrão de análise.

An Instanté um momento na linha do tempo no UTC .

Instant instant = Instant.parse( "2013-09-29T18:46:19Z" );

Você pode aplicar um fuso horário conforme necessário para produzir um ZonedDateTimeobjeto.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );

Tabela de tipos de data e hora em Java, modernos e herdados

Basil Bourque
fonte
22

e se você não tiver a opção de continuar com o java8, use 'aaaa-MM-dd'T'HH: mm: ssX XX ', pois isso será analisado corretamente novamente (enquanto que com apenas um X isso pode não ser o caso. .. dependendo da sua função de análise)

X gera: +01

XXX gera: +01: 00

Thirdman
fonte
0

Para Java 8: você pode usar o embutido java.time.format.DateTimeFormatterpara reduzir qualquer chance de erros de digitação, como

DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;

ISO_ZONED_DATE_TIME representa 2011-12-03T10:15:30+01:00[Europe/Paris]um dos formatos padrão de DateTime fornecidos pelo link Oracle

niraj
fonte