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é les SimpleDateFormats suivants pour l’parsingr:

 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 les formats tels que:

 public static Date figureOutTheDamnDate(Ssortingng 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 bash sur le motif yyyyMMddHHmm mais renvoie la date comme Thu Dec 03 00:01:00 PST 2009 .

Quel est le schéma correct pour parsingr cette date?

MISE À JOUR: Je n’ai pas besoin de l’parsing du fuseau horaire. Je ne pense pas avoir de problèmes de temps qui se déplacent entre les zones, mais comment puis-je parsingr le format de zone “-08: 00”?

Test de l’unité:

 @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")); } 

Sortie du test unitaire:

 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 

DateTimeFormat de JodaTime pour sauver:

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

(la différence d’heure et de fuseau horaire dans toSsortingng() est due au fait que je suis à GMT-4 et que je n’ai pas défini explicitement les parameters régionaux)

Si vous voulez vous retrouver avec java.util.Date utilisez simplement DateTime#toDate() :

 Date date = dateTime.toDate(); 

Attendez JDK7 ( JSR-310 ) JSR-310, l’implémentation de la référence est appelée ThreeTen (en espérant que cela deviendra Java 8) si vous voulez un meilleur formateur dans l’API Java SE standard. Le SimpleDateFormat actuel ne mange en effet pas les deux points dans la notation du fuseau horaire.

Mise à jour : selon la mise à jour, vous n’avez apparemment pas besoin du fuseau horaire. Cela devrait fonctionner avec SimpleDateFormat . Il suffit de l’omettre (le Z ) dans le motif.

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

(ce qui est correct selon mon fuseau horaire)

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

 public static void main(Ssortingng[] args) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") { public SsortingngBuffer format(Date date, SsortingngBuffer toAppendTo, java.text.FieldPosition pos) { SsortingngBuffer 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 

Si vous utilisiez le java 7, vous auriez pu utiliser le modèle de date et heure suivant. Il semble que ce modèle ne soit pas pris en charge dans la version antérieure de java.

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

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

Essayez ceci, son travail pour moi:

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

Dans Java 8:

 OffsetDateTime dt = OffsetDateTime.parse("2010-03-01T00:00:00-08:00"); 

Si vous pouvez utiliser JDK 1.7 ou supérieur, essayez ceci:

 public class DateUtil { private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); public static Ssortingng format(Date date) { return dateFormat.format(date); } public static Date parse(Ssortingng dateSsortingng) throws AquariusException { try { return dateFormat.parse(dateSsortingng); } catch (ParseException e) { throw new AquariusException(e); } } } 

document: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html qui prend en charge un nouveau format de fuseau horaire “XXX” (par exemple -3: 00)

Alors que JDK 1.6 ne supporte que d’autres formats pour le fuseau horaire, qui sont “z” (par exemple NZST), “zzzz” (par exemple, heure standard de Nouvelle-Zélande), “Z” (par exemple +1200), etc.

tl; dr

 OffsetDateTime.parse( "2010-03-01T00:00:00-08:00" ) 

Détails

La réponse de BalusC est correcte, mais maintenant obsolète à partir de Java 8.

java.time

Le framework java.time est le successeur de la bibliothèque Joda-Time et des anciennes classes de date / heure gênantes associées aux premières versions de Java (java.util.Date/.Calendar & java.text.SimpleDateFormat).

ISO 8601

Votre chaîne de données d’entrée est conforme à la norme ISO 8601 .

Les classes java.time utilisent les formats ISO 8601 par défaut lors de l’parsing / génération de représentations textuelles des valeurs date-heure. Donc, pas besoin de définir un modèle de formatage.

OffsetDateTime

La classe OffsetDateTime représente un moment de la ligne de temps ajusté à un décalage particulier à partir de UTC . Dans votre saisie, le décalage est de 8 heures derrière l’UTC, couramment utilisé sur la majeure partie de la côte ouest de l’Amérique du Nord.

 OffsetDateTime odt = OffsetDateTime.parse( "2010-03-01T00:00:00-08:00" ); 

Vous semblez vouloir la date uniquement, auquel cas utilisez la classe LocalDate . Mais gardez à l’esprit que vous ignorez les données, (a) l’heure du jour et (b) le fuseau horaire. En réalité, une date n’a pas de sens sans le contexte d’un fuseau horaire . Pour un moment donné, la date varie dans le monde entier. Par exemple, juste après minuit à Paris, c’est encore «hier» à Montréal. Donc, même si je suggère de coller avec les valeurs date-heure, vous pouvez facilement convertir en un LocalDate si vous insistez.

 LocalDate localDate = odt.toLocalDate(); 

Fuseau horaire

Si vous connaissez le fuseau horaire prévu, appliquez-le. Un fuseau horaire est un décalage plus les règles à utiliser pour gérer les anomalies telles que l’ heure d’été . L’application d’un ZoneId nous procure un object ZonedDateTime .

 ZoneId zoneId = ZoneId.of( "America/Los_Angeles" ); ZonedDateTime zdt = odt.atZoneSameInstant( zoneId ); 

Générer des chaînes

Pour générer une chaîne au format ISO 8601, appelez toSsortingng .

 Ssortingng output = odt.toSsortingng(); 

Si vous avez besoin de chaînes dans d’autres formats, recherchez Stack Overflow pour utiliser le package java.util.format .

Conversion en java.util.Date

Mieux java.util.Date éviter java.util.Date , mais si vous devez, vous pouvez convertir. Appelez les nouvelles méthodes ajoutées aux anciennes classes, telles que java.util.Date.from où vous passez un Instant . Un Instant est un moment de la chronologie en UTC . Nous pouvons extraire un Instant de notre OffsetDateTime .

 java.util.Date utilDate = java.util.Date( odt.toInstant() ); 

À propos de java.time

Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes classes de date / heure héritées telles que java.util.Date , Calendar et SimpleDateFormat .

Le projet Joda-Time , maintenant en mode maintenance , conseille la migration vers les classes java.time .

Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .

Vous pouvez échanger des objects java.time directement avec votre firebase database. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de classes java.sql.* .

Où obtenir les classes java.time?

  • Java SE 8 , Java SE 9 , Java SE 10 et versions ultérieures
    • Intégré
    • Partie de l’API Java standard avec une implémentation intégrée.
    • Java 9 ajoute quelques fonctionnalités et corrections mineures.
  • Java SE 6 et Java SE 7
    • Une grande partie de la fonctionnalité java.time est transférée vers Java 6 et 7 dans ThreeTen-Backport .
  • Android
    • Versions ultérieures des implémentations de bundles Android des classes java.time .
    • Pour Android antérieur (<26), le projet ThreeTenABP adapte ThreeTen-Backport (mentionné ci-dessus). Voir Comment utiliser ThreeTenABP… .

Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d’essai pour d’éventuels ajouts futurs à java.time. Vous pouvez y trouver des classes utiles telles que Interval , YearWeek , YearQuarter , etc.

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

 public static final SimpleDateFormat XML_SDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.FRANCE) { private static final long serialVersionUID = -8275126788734707527L; public SsortingngBuffer format(Date date, SsortingngBuffer toAppendTo, java.text.FieldPosition pos) { final SsortingngBuffer buf = super.format(date, toAppendTo, pos); buf.insert(buf.length() - 2, ':'); return buf; }; public Date parse(Ssortingng source) throws java.text.ParseException { final int split = source.length() - 2; return super.parse(source.subssortingng(0, split - 1) + source.subssortingng(split)); // replace ":" du TimeZone }; }; 

Essayez setLenient(false) .

Addendum: On dirait que vous reconnaissez des chaînes de Date format différent. Si vous devez faire une entrée, vous voudrez peut-être regarder cet exemple qui étend InputVerifier .

Comme un exemple d’Apache FastDateFormat (cliquez pour les documentations des versions: 2.6 et 3.5 ) est manquant ici, j’en ajoute un pour ceux qui en ont besoin. La clé ici est le motif ZZ (2 Z majuscules).

 import java.text.ParseException import java.util.Date; import org.apache.commons.lang3.time.FastDateFormat; public class DateFormatTest throws ParseException { public static void main(Ssortingng[] args) { Ssortingng ssortingngDateFormat = "yyyy-MM-dd'T'HH:mm:ssZZ"; FastDateFormat fastDateFormat = FastDateFormat.getInstance(ssortingngDateFormat); System.out.println("Date formatted into Ssortingng:"); System.out.println(fastDateFormat.format(new Date())); Ssortingng ssortingngFormattedDate = "2016-11-22T14:30:14+05:30"; System.out.println("Ssortingng parsed into Date:"); System.out.println(fastDateFormat.parse(ssortingngFormattedDate)); } } 

Voici la sortie du code:

 Date formatted into Ssortingng: 2016-11-22T14:52:17+05:30 Ssortingng parsed into Date: Tue Nov 22 14:30:14 IST 2016 

Note: Le code ci-dessus est de Apache Commons ‘lang3. La classe org.apache.commons.lang.time.FastDateFormat ne prend pas en charge l’parsing, et prend uniquement en charge le formatage. Par exemple, la sortie du code suivant:

 import java.text.ParseException; import java.util.Date; import org.apache.commons.lang.time.FastDateFormat; public class DateFormatTest { public static void main(Ssortingng[] args) throws ParseException { Ssortingng ssortingngDateFormat = "yyyy-MM-dd'T'HH:mm:ssZZ"; FastDateFormat fastDateFormat = FastDateFormat.getInstance(ssortingngDateFormat); System.out.println("Date formatted into Ssortingng:"); System.out.println(fastDateFormat.format(new Date())); Ssortingng ssortingngFormattedDate = "2016-11-22T14:30:14+05:30"; System.out.println("Ssortingng parsed into Date:"); System.out.println(fastDateFormat.parseObject(ssortingngFormattedDate)); } } 

sera ceci:

 Date formatted into Ssortingng: 2016-11-22T14:55:56+05:30 Ssortingng parsed into Date: Exception in thread "main" java.text.ParseException: Format.parseObject(Ssortingng) failed at java.text.Format.parseObject(Format.java:228) at DateFormatTest.main(DateFormatTest.java:12) 

Vous pouvez utiliser X dans Java 7.

https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

 public class DateTest { public static final SimpleDateFormat JSON_DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); private Ssortingng date = "2016-12-01 22:05:30"; private Ssortingng requireDate = "2016-12-01T22:05:30+03:00"; @Test public void parseDateToBinBankFormat() throws ParseException { Ssortingng format = JSON_DATE_TIME_FORMAT.format(DATE_TIME_FORMAT.parse(date)); System.out.println(format); Assert.assertEquals(format, requireDate); } } 

Si la chaîne de date est comme 2018-07-20T12: 18: 29.802Z Utilisez ceci

 SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");