Caractère de modèle illégal ‘T’ lors de l’parsing d’une chaîne de date en java.util.Date

J’ai une chaîne de date et je veux l’parsingr à la date normale en utilisant l’API de date java, voici mon code:

public static void main(Ssortingng[] args) { Ssortingng date="2010-10-02T12:23:23Z"; Ssortingng pattern="yyyy-MM-ddThh:mm:ssZ"; SimpleDateFormat sdf=new SimpleDateFormat(pattern); try { Date d=sdf.parse(date); System.out.println(d.getYear()); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 

Cependant, j’ai une exception: java.lang.IllegalArgumentException: Illegal pattern character 'T'

Donc, je me demande si je dois diviser la chaîne et l’parsingr manuellement?

BTW, j’ai essayé d’append un seul caractère de citation de chaque côté du T:

 Ssortingng pattern="yyyy-MM-dd'T'hh:mm:ssZ"; 

Cela ne fonctionne pas non plus.

Mise à jour pour Java 8 et supérieur

Vous pouvez maintenant faire simplement Instant.parse("2015-04-28T14:23:38.521Z") et obtenir la bonne chose maintenant, surtout que vous devriez utiliser Instant au lieu de java.util.Date avec les versions les plus récentes. de Java

Vous devriez également utiliser DateTimeFormatter au lieu de SimpleDateFormatter .

Réponse originale:

L’explication ci-dessous est toujours valable comme ce que représente le format. Mais il a été écrit avant que Java 8 ne soit omniprésent, il utilise donc les anciennes classes que vous ne devriez pas utiliser si vous utilisez Java 8 ou supérieur.

Cela fonctionne avec l’entrée avec le Z final comme démontré:

Dans le modèle, le T est échappé avec ' de chaque côté.

Le modèle pour le Z à la fin est en fait XXX comme indiqué dans le JavaDoc pour SimpleDateFormat , il n’est pas très clair sur la façon de l’utiliser puisque Z est également le marqueur des anciennes informations TimeZone .

Q2597083.java

 import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; public class Q2597083 { /** * All Dates are normalized to UTC, it is up the client code to convert to the appropriate TimeZone. */ public static final TimeZone UTC; /** * @see Combined Date and Time Representations */ public static final Ssortingng ISO_8601_24H_FULL_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; /** * 0001-01-01T00:00:00.000Z */ public static final Date BEGINNING_OF_TIME; /** * 292278994-08-17T07:12:55.807Z */ public static final Date END_OF_TIME; static { UTC = TimeZone.getTimeZone("UTC"); TimeZone.setDefault(UTC); final Calendar c = new GregorianCalendar(UTC); c.set(1, 0, 1, 0, 0, 0); c.set(Calendar.MILLISECOND, 0); BEGINNING_OF_TIME = c.getTime(); c.setTime(new Date(Long.MAX_VALUE)); END_OF_TIME = c.getTime(); } public static void main(Ssortingng[] args) throws Exception { final SimpleDateFormat sdf = new SimpleDateFormat(ISO_8601_24H_FULL_FORMAT); sdf.setTimeZone(UTC); System.out.println("sdf.format(BEGINNING_OF_TIME) = " + sdf.format(BEGINNING_OF_TIME)); System.out.println("sdf.format(END_OF_TIME) = " + sdf.format(END_OF_TIME)); System.out.println("sdf.format(new Date()) = " + sdf.format(new Date())); System.out.println("sdf.parse(\"2015-04-28T14:23:38.521Z\") = " + sdf.parse("2015-04-28T14:23:38.521Z")); System.out.println("sdf.parse(\"0001-01-01T00:00:00.000Z\") = " + sdf.parse("0001-01-01T00:00:00.000Z")); System.out.println("sdf.parse(\"292278994-08-17T07:12:55.807Z\") = " + sdf.parse("292278994-08-17T07:12:55.807Z")); } } 

Produit la sortie suivante:

 sdf.format(BEGINNING_OF_TIME) = 0001-01-01T00:00:00.000Z sdf.format(END_OF_TIME) = 292278994-08-17T07:12:55.807Z sdf.format(new Date()) = 2015-04-28T14:38:25.956Z sdf.parse("2015-04-28T14:23:38.521Z") = Tue Apr 28 14:23:38 UTC 2015 sdf.parse("0001-01-01T00:00:00.000Z") = Sat Jan 01 00:00:00 UTC 1 sdf.parse("292278994-08-17T07:12:55.807Z") = Sun Aug 17 07:12:55 UTC 292278994 

tl; dr

 Instant.parse( "2010-10-02T12:23:23Z" ) 

ISO 8601

Ce format est défini par la norme ISO 8601 pour les formats de chaîne date-heure.

Tous les deux:

  • framework java.time intégré à Java 8 et versions ultérieures ( tutoriel )
  • Bibliothèque Joda-Time

… Utilisez les formats ISO 8601 par défaut pour parsingr et générer des chaînes.

Vous devez généralement éviter d’utiliser les anciennes classes java.util.Date /.Calendar & java.text.SimpleDateFormat car elles sont notoirement difficiles, confuses et erronées. Si nécessaire pour l’interopérabilité, vous pouvez convertir en va-et-vient.

java.time

Le nouveau framework java.time est intégré à Java 8 et aux versions ultérieures . Inspiré par Joda-Time , défini par JSR 310 , et étendu par le projet ThreeTen-Extra .

 Instant instant = Instant.parse( "2010-10-02T12:23:23Z" ); // `Instant` is always in UTC. 

Convertir à l’ancienne classe.

 java.util.Date date = java.util.Date.from( instant ); // Pass an `Instant` to the `from` method. 

Fuseau horaire

Si nécessaire, vous pouvez affecter un fuseau horaire.

 ZoneId zoneId = ZoneId.of( "America/Montreal" ); // Define a time zone rather than rely implicitly on JVM's current default time zone. ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId ); // Assign a time zone adjustment from UTC. 

Convertir.

 java.util.Date date = java.util.Date.from( zdt.toInstant() ); // Extract an `Instant` from the `ZonedDateTime` to pass to the `from` method. 

Joda-Time

UPDATE: Le projet Joda-Time est maintenant en mode maintenance. L’équipe conseille la migration vers les classes java.time .

Voici un exemple de code dans Joda-Time 2.8.

 org.joda.time.DateTime dateTime_Utc = new DateTime( "2010-10-02T12:23:23Z" , DateTimeZone.UTC ); // Specifying a time zone to apply, rather than implicitly assigning the JVM's current default. 

Convertir en ancienne classe. Notez que le fuseau horaire atsortingbué est perdu dans la conversion, car juDate ne peut pas être affecté à un fuseau horaire.

 java.util.Date date = dateTime_Utc.toDate(); // The `toDate` method converts to old class. 

Fuseau horaire

Si nécessaire, vous pouvez affecter un fuseau horaire.

 DateTimeZone zone = DateTimeZone.forID( "America/Montreal" ); DateTime dateTime_Montreal = dateTime_Utc.withZone ( zone ); 

À 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 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.