web-dev-qa-db-fra.com

Java Modèle SimpleDateFormat pour les dates XML W3C avec fuseau horaire

J'essaie d'analyser une W3C date du schéma XML comme suit

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

qui est conforme à la version ISO 8601 de la spécification Schéma XML W3C dateTime .

Dans la date ci-dessus, l'identifiant de fuseau horaire est "+03:00", mais aucun modèle SimpleDateFormat n'existe apparemment pour le représenter.

Si le fuseau horaire était "+0300", alors Z (majuscule) serait applicable et le modèle SimpleDateFormat serait

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

De même, si le fuseau horaire était "GMT+03:00", alors z (minuscule) serait applicable et le modèle SimpleDateFormat serait

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

(majuscule 'Z' fonctionne aussi d'ailleurs).

Alors, existe-t-il un modèle ou une solution de contournement SimpleDateFormat pour représenter la date ci-dessus sans prétraitement de la chaîne de date?

29
PNS

Que diriez-vous de quelque chose comme:

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);
    }
};
24
Vlad

Si vous utilisez Java 7+, ce modèle devrait fonctionner (X correspond au fuseau horaire ISO 8601):

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

Hmmm le format de date ressemble au format de type de données XML datetime? S'il s'agit d'un format de type de données XML datetime, vous pouvez utiliser javax.xml.datatype.DatatypeFactory pour créer XMLGregorianCalendar

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

L'appel ci-dessus renvoie une instance de XMLGregorianCalendar, vous pouvez utiliser l'objet pour le convertir en d'autres objets datJava datetime comme GregorianCalendar.

11
Alvin

utilisez Apache commons DateUtils avec des modèles possibles. 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;
              }
3
Shailesh Prabhu

Non, il n'y a pas de solution pour que SimpleDateFormat comprenne ce format sans prétraiter la chaîne (par exemple en supprimant le : de la chaîne). (edit: sauf si vous utilisez Java 7 ou plus récent comme indiqué par assylias).

Il semble que vous essayiez d'analyser des chaînes au format XML standard pour les dates et les heures (ISO 8601). Je recommanderais d'utiliser la bibliothèque Joda Time qui a prise en charge de ce format .

Si vous ne pouvez pas ou ne voulez pas utiliser Joda Time pour une raison quelconque, vous pouvez utiliser les classes du package javax.xml.datatype pour analyser et formater les horodatages dans ce format. Par exemple:

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();
3
Jesper

La meilleure façon est d'utiliser les Joda

org.joda.time.format.ISODateTimeFormat

Cordialement,

2
Peter Rader

Vous pouvez essayer quelque chose comme:

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

Je ne sais pas très bien si cela fonctionnera pour vous ou non. Mais voici le code que j'ai essayé lors de la conversion de la date d'un fuseau horaire à un autre fuseau horaire. Puisse une partie du code vous aider.

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;
    }

J'espère que cela vous aidera. À votre santé. :)

1
Japan Trivedi

En ce qui concerne SimpleDateFormat, vous avez déjà mentionné les modèles de format disponibles et définis dans: http://docs.Oracle.com/javase/7/docs/api/Java/text/SimpleDateFormat.html

Si vous voulez faire plus avec votre date, GregorianCalendar vous donne plus d'options, par exemple:

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