72 votes

Java SimpleDateFormat pour le fuseau horaire avec un séparateur de deux points?

J'ai une date dans le format suivant: 2010-03-01T00:00:00-08:00

J'ai jeté la suite SimpleDateFormats pour l'analyser:

private static final SimpleDateFormat[] FORMATS = {
        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"), //ISO8601 long RFC822 zone
        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"), //ISO8601 long long form zone
        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"), //ignore timezone
        new SimpleDateFormat("yyyyMMddHHmmssZ"), //ISO8601 short
        new SimpleDateFormat("yyyyMMddHHmm"),
        new SimpleDateFormat("yyyyMMdd"), //birthdate from NIST IHE C32 sample
        new SimpleDateFormat("yyyyMM"),
        new SimpleDateFormat("yyyy") //just the year
    };

J'ai une méthode pratique qui utilise ces formats comme:

public static Date figureOutTheDamnDate(String wtf) {
    if (wtf == null) {
        return null;
    }
    Date retval = null;
    for (SimpleDateFormat sdf : FORMATS) {
        try {
            sdf.setLenient(false)
            retval = sdf.parse(wtf);
            System.out.println("Date:" + wtf + " hit on pattern:" + sdf.toPattern());
            break;
        } catch (ParseException ex) {
            retval = null;
            continue;
        }
    }

    return retval;
}

Il semble frappé sur le modèle yyyyMMddHHmm mais retourne la date sous la forme Thu Dec 03 00:01:00 PST 2009.

Est-ce le bon modèle pour analyser cette date?

Mise à JOUR: je n'ai pas BESOIN de temps de la zone d'analyse. Je ne pense pas avoir le temps questions sensibles de déplacement entre les zones, mais comment pourrais-je obtenir le "-08:00" zone format à analyser????

Unité de test:

@Test
public void test_date_parser() {
    System.out.println("\ntest_date_parser");
    //month is zero based, are you effing kidding me
    Calendar d = new GregorianCalendar(2000, 3, 6, 13, 00, 00);
    assertEquals(d.getTime(), MyClass.figureOutTheDamnDate("200004061300"));
    assertEquals(new GregorianCalendar(1950, 0, 1).getTime(), MyClass.figureOutTheDamnDate("1950"));
    assertEquals(new GregorianCalendar(1997, 0, 1).getTime(),  MyClass.figureOutTheDamnDate("199701"));
    assertEquals(new GregorianCalendar(2010, 1, 25, 15, 19, 44).getTime(),   MyClass.figureOutTheDamnDate("20100225151944-0800"));

    //my machine happens to be in GMT-0800
    assertEquals(new GregorianCalendar(2010, 1, 15, 13, 15, 00).getTime(),MyClass.figureOutTheDamnDate("2010-02-15T13:15:00-05:00"));
    assertEquals(new GregorianCalendar(2010, 1, 15, 18, 15, 00).getTime(), MyClass.figureOutTheDamnDate("2010-02-15T18:15:00-05:00"));

    assertEquals(new GregorianCalendar(2010, 2, 1).getTime(), MyClass.figureOutTheDamnDate("2010-03-01T00:00:00-08:00"));
    assertEquals(new GregorianCalendar(2010, 2, 1, 17, 0, 0).getTime(), MyClass.figureOutTheDamnDate("2010-03-01T17:00:00-05:00"));
}

De sortie de l'unité de test:

test_date_parser
Date:200004061300 hit on pattern:yyyyMMddHHmm
Date:1950 hit on pattern:yyyy
Date:199701 hit on pattern:yyyyMM
Date:20100225151944-0800 hit on pattern:yyyyMMddHHmmssZ
Date:2010-02-15T13:15:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-02-15T18:15:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-03-01T00:00:00-08:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-03-01T17:00:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss

62voto

BalusC Points 498232

JodaTimes' DateTimeFormat de sauvetage:

String dateString = "2010-03-01T00:00:00-08:00";
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
DateTimeFormatter dtf = DateTimeFormat.forPattern(pattern);
DateTime dateTime = dtf.parseDateTime(dateString);
System.out.println(dateTime); // 2010-03-01T04:00:00.000-04:00

(le temps et la différence de fuseau horaire en toString() est juste parce que je suis à GMT-4 et de ne pas définir les paramètres régionaux de manière explicite)

Si vous voulez retrouver avec java.util.Date suffit d'utiliser DateTime#toDate():

Date date = dateTime.toDate();

Attendre JDK7 (JSR 310) JSR 310, le referrence mise en œuvre est appelée ThreeTen (j'espère qu'il va le faire en Java 8) si vous voulez une meilleure formateur dans le standard de l'API Java SE. Le courant SimpleDateFormat , en effet, ne pas manger le côlon dans le fuseau horaire de notation.

Mise à jour: selon la mise à jour, apparemment vous n'avez pas besoin de le fuseau horaire. Cela devrait aussi fonctionner avec SimpleDateFormat. Juste omettre (l' Z) dans le modèle.

String dateString = "2010-03-01T00:00:00-08:00";
String pattern = "yyyy-MM-dd'T'HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
Date date = sdf.parse(dateString);
System.out.println(date); // Mon Mar 01 00:00:00 BOT 2010

(ce qui est correct comme pour mon fuseau horaire)

47voto

YouEyeK Points 41

si vous utilisiez java 7, vous auriez pu utiliser le modèle Date-Heure suivant. On dirait que ce modèle n'est pas pris en charge dans la version antérieure de java.

 String dateTimeString  = "2010-03-01T00:00:00-08:00";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
Date date = df.parse(dateTimeString);
 

Pour plus d'informations, reportez-vous à la documentation SimpleDateFormat .

36voto

acdcjunior Points 19898

Voici un extrait que j'ai utilisé - avec%% SimpleDateFormat . J'espère que quelqu'un d'autre pourra en bénéficier:

 public static void main(String[] args) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") {
        public StringBuffer format(Date date, StringBuffer toAppendTo, java.text.FieldPosition pos) {
            StringBuffer toFix = super.format(date, toAppendTo, pos);
            return toFix.insert(toFix.length()-2, ':');
        };
    };
    // Usage:
    System.out.println(dateFormat.format(new Date()));
}
 

Sortie:

 - Usual Output.........: 2013-06-14T10:54:07-0200
- This snippet's Output: 2013-06-14T10:54:07-02:00
 

15voto

Rustam Points 96

Essayez ceci, son travail pour moi:

 Date date = javax.xml.bind.DatatypeConverter.parseDateTime("2013-06-01T12:45:01+04:00").getTime();
 

4voto

Bludwarf Points 58

Merci acdcjunior pour votre solution. Voici une petite version optimisée pour le formatage et l'analyse :

 public static final SimpleDateFormat XML_SDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.FRANCE)
{
    private static final long serialVersionUID = -8275126788734707527L;

    public StringBuffer format(Date date, StringBuffer toAppendTo, java.text.FieldPosition pos)
    {            
        final StringBuffer buf = super.format(date, toAppendTo, pos);
        buf.insert(buf.length() - 2, ':');
        return buf;
    };

    public Date parse(String source) throws java.text.ParseException {
        final int split = source.length() - 2;
        return super.parse(source.substring(0, split - 1) + source.substring(split)); // replace ":" du TimeZone
    };
};
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X