Padrão Java SimpleDateFormat para W3C XML datas com fuso horário

Eu estou tentando analisar uma data de esquema XML W3C como o seguinte

"2012-05-15T07:08:09+03:00" 

que está em conformidade com a versão ISO 8601 da especificação dateTime do Esquema XML do W3C .

Na data acima, o identificador de fuso horário é "+03:00" , mas aparentemente não existe um padrão SimpleDateFormat para representá-lo.

Se o fuso horário fosse "+0300" , então Z (maiúscula) seria aplicável e o padrão SimpleDateFormat seria

 yyyy-MM-dd'T'HH:mm:ssZ 

Da mesma forma, se o fuso horário fosse "GMT+03:00" , então z (minúsculas) seria aplicável e o padrão SimpleDateFormat seria

 yyyy-MM-dd'T'HH:mm:ssz 

(maiúsculas 'Z' também funciona, a propósito).

Então, existe um padrão SimpleDateFormat ou uma solução alternativa para representar a data acima sem o pré-processamento da string de data?

Que tal algo como:

 DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"){ public Date parse(String source,ParsePosition pos) { return super.parse(source.replaceFirst(":(?=[0-9]{2}$)",""),pos); } }; 

Se você usar o Java 7+, esse padrão deverá funcionar ( X é para o fuso horário ISO 8601):

 SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"); 

Hmmm o formato de data se parece com o formato de tipo de dados XML datetime? Se for formato de tipo de dados XML datetime, você poderá usar javax.xml.datatype.DatatypeFactory para criar XMLGregorianCalendar

 DatatypeFactory .newInstance() .newXMLGregorianCalendar("2012-05-15T07:08:09+03:00"); 

A chamada acima retorna a instância de XMLGregorianCalendar você pode usar o object para converter em outros objects de data e hora de Java, como GregorianCalendar .

Não, não há nenhuma solução alternativa para tornar o SimpleDateFormat entender esse formato sem pré-processar a cadeia (por exemplo, removendo o : da cadeia). (edit: exceto se você estiver usando o Java 7 ou mais recente, conforme observado por assylias).

Parece que você está tentando analisar strings no formato XML padrão para datas e horas (ISO 8601). Eu recomendaria usar a biblioteca Joda Time , que tem suporte para este formato .

Se você não pode ou não quer usar o Joda Time por algum motivo, então você pode usar classs do pacote javax.xml.datatype para analisar e formatar timestamps nesse formato. Por exemplo:

 DatatypeFactory factory = DatatypeFactory.newInstance(); // Parses a string in ISO 8601 format to an XMLGregorianCalendar XMLGregorianCalendar xmlCal = factory.newXMLGregorianCalendar("2012-05-16T10:39:00+03:00"); // Convert it to a regular java.util.Calendar Calendar cal = xmlCal.toGregorianCalendar(); 

use Apache commons DateUtils com possíveis padrões. Ex:

 private static final String[] DATE_FORMATS = new String[] { "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ssz", "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-ddz", "yyyy-MM-ddZ" }; public Date parse(String date) { Date parsedDate = null; try { parsedDate = DateUtils.parseDate(date, DATE_FORMATS); } catch (ParseException e) { logger.error("dates should be in valid format" + e); return null; } return parsedDate; } 

A melhor maneira é usar o Joda’s

 org.joda.time.format.ISODateTimeFormat 

Saudações,

Com relação ao SimpleDateFormat, você já mencionou os padrões de formato disponíveis e eles estão definidos em: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

Se você quiser fazer mais com sua data, GregorianCalendar lhe dará mais opções, por exemplo:

 TimeZone zone = TimeZone.getTimeZone(TimeZone.getTimeZone("GMT-8").getID()); GregorianCalendar calendar = new GregorianCalendar(zone); calendar.setTime(new Date(SomeDate)); 

Você pode tentar algo como:

 DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"); Date date = df.parse(stringDate.replaceAll("\\+", "GMT+")); 

Não tenho certeza se isso funcionará para você ou não. Mas aqui o código que tentei ao converter data de um fuso horário para outro fuso horário. Pode alguma parte do código pode ajudá-lo.

 public Date convertToUserTimezone(long dateToConvert, String timezoneOffset){ java.text.DateFormat format = SimpleDateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);/*new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");*/ // java.util.Calendar cal = Calendar.getInstance(new // SimpleTimeZone(0, "GMT+05:30")); TimeZone gmtTime = TimeZone.getTimeZone("GMT"+timezoneOffset); format.setTimeZone(gmtTime); java.util.Date date1 = new Date(format.format(new Date(dateToConvert))); return date1; } 

Espero que isso ajude você. Felicidades. 🙂