web-dev-qa-db-fra.com

Comment convertir une date dans ce format (Tue Jul 13 00:00:00 CEST 2010) en une Java Date (la chaîne provient d'une propriété en plein air)

je gère une date qui provient d'une propriété Alfresco et qui se trouve dans la date spécifiée (mar juil 13 00:00:00 CEST 2010) et j'ai besoin de la convertir en date Java date .. J'ai regardé autour de moi et trouvé des millions de messages pour diverses formes de conversion de chaîne en date et aussi cette page et j'ai donc essayé quelque chose comme ceci:

private static final DateFormat alfrescoDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
Date dataRispostaDate = alfrescoDateFormat.parse(dataRisposta);

Mais il lève une exception. (L'exception est (SSollevata un'eccezione durante la gestione della data: Java.text.ParseException: date non analysable: "Tue Jul 13 00:00:00 CEST 2011").

Je poste le code complet:

        try {
            QName currDocTypeQName = (QName) nodeService.getType(doc);
            log.error("QName:["+currDocTypeQName.toString()+"]");
            if (currDocTypeQName != null) {
                String codAtto = AlfrescoConstants.getCodAttoFromQName(currDocTypeQName.toString());
                log.error("codAtto:["+codAtto+"]");
                if (codAtto.equals(AlfrescoConstants.COD_IQT)){
                    List<ChildAssociationRef> risposteAssociate = nodeService.getChildAssocs(doc, AlfrescoConstants.QN_RISPOSTEASSOCIATE, RegexQNamePattern.MATCH_ALL);
                    for (ChildAssociationRef childAssocRef : risposteAssociate) {
                        // Vado a prendere il nodo
                        NodeRef risposta = childAssocRef.getChildRef();
                        String dataRisposta = (nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA)).toString();
                        log.error("dataRisposta:["+dataRisposta+"]");
                        if (!dataRisposta.isEmpty()){
                            try {
                                Date dataDa = dmyFormat.parse(req.getParameter("dataDa"));
                                log.error("dataDa:["+dataDa.toString()+"]");
                                Date dataA = dmyFormat.parse(req.getParameter("dataA"));
                                log.error("dataA:["+dataA.toString()+"]");
                                Date dataRispostaDate = alfrescoDateFormat.parse(dataRisposta);
                                log.error("dataRispostaDate:["+dataRispostaDate.toString()+"]");

                                if (dataRispostaDate.after(dataDa) && dataRispostaDate.before(dataA)){
                                    results.add(doc);
                                    log.error("La data risposta  è compresa tra le date specificate");
                                }else{
                                    log.error("La data risposta non è compresa tra le date specificate");
                                }
                            } catch (ParseException e) {
                                log.error("Sollevata un'eccezione durante la gestione della data: " + e);
                                throw new RuntimeException("Formato data non valido");
                            }
                        }else{
                            log.error("La data risposta non è specificata");
                        }
                    }
                }else{
                    results.add(doc);
                }
            }
        } catch (Exception e) {
            log.error("Sollevata un'eccezione durante la gestione del codice atto nel webscript nicola: " + e);
        }

Tout le monde peut aider?

17

Fondamentalement, votre le problème est que vous utilisez un constructeur SimpleDateFormat (String pattern) , où javadoc dit:

Construit un SimpleDateFormat en utilisant le modèle donné et les symboles de format de date par défaut pour le locale par défaut.

Et si vous essayez d'utiliser ce code:

DateFormat osLocalizedDateFormat = new SimpleDateFormat("MMMM EEEE");
System.out.println(osLocalizedDateFormat.format(new Date()))

vous remarquerez qu'il imprime les titres du mois et du jour de la semaine en fonction de votre environnement local.

La solution à votre problème est pour remplacer les paramètres régionaux de date par défaut à l'aide de SimpleDateFormat (modèle de chaîne, paramètres régionaux de paramètres régionaux) constructeur:

DateFormat dateFormat = new SimpleDateFormat(
            "EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
dateFormat.parse("Tue Jul 13 00:00:00 CEST 2011");
System.out.println(dateFormat.format(new Date()));
23
JMelnik

Sur la base de vos commentaires, je pense que votre propriété est en fait de type d: date ou d: datetime. Si c'est le cas, la propriété reviendra déjà d'Alfresco en tant qu'objet Java Date. Donc, tout ce que vous aurez à faire est de:

  NodeRef risposta = childAssocRef.getChildRef();
  Date dataRisposta = (Date)nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA);
6
Gagravarr

tl; dr

ZonedDateTime.parse(                     // Produce a `Java.time.ZonedDateTime` object.
    "Wed Jul 13 00:00:00 CEST 2011" ,    // Corrected `Tue` to `Wed`.
    DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss zzz uuuu" , Locale.US  ) 
)

2011-07-13T00: 00 + 02: 00 [Europe/Paris]

Données incorrectes: Wed vs Tue

Vous entrez une chaîne Tue Jul 13 00:00:00 CEST 2011 est invalide. Le 13 juillet 2011 était un mercredi et non un mardi .

String input = "Wed Jul 13 00:00:00 CEST 2011" ;  // Corrected `Tue` to `Wed`.

screen shot of July 2011 calendar in Duck Duck Go search engine

Java.time

L'approche moderne utilise les classes Java.time plutôt que les anciennes classes de date-heure héritées gênantes vues dans d'autres réponses.

Définissez un modèle de mise en forme pour correspondre à votre chaîne d'entrée. Notez le Locale , qui définit le langage humain à utiliser pour analyser le nom du mois et le nom du jour de la semaine.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss zzz uuuu" , Locale.US  );
ZonedDateTime zdt = ZonedDateTime.parse( input , f  );

zdt.toString (): 2011-07-13T00: 00 + 02: 00 [Europe/Paris]

Fuseau horaire

Votre CEST est une pseudo-zone, pas un vrai fuseau horaire. Ne les utilisez jamais. Ils ne sont pas standardisés et ne sont même pas uniques (!).

La classe ZonedDateTime fera un vaillant effort pour deviner l'intention derrière une telle pseudo-zone de 3-4 caractères. Votre CEST a fonctionné ici, interprété comme Europe/Paris fuseau horaire. Mais vous ne pouvez pas compter sur le succès à 100%. Au lieu de cela, évitez complètement ces pseudo-zones .

Spécifiez un nom de fuseau horaire correct au format continent/region, comme America/Montreal , Africa/Casablanca , ou Pacific/Auckland.

ZoneId z = ZoneId.of( "Europe/Paris" );  // https://time.is/Paris
LocalDate today = LocalDate.now( z );  // Current date varies around the globe by zone.

ISO 8601

Le format de votre chaîne d'entrée est terrible. Lors de la sérialisation des valeurs date-heure sous forme de texte, utilisez uniquement les formats standard ISO 8601 .

La classe ZonedDateTime étend judicieusement le format standard en ajoutant le nom du fuseau horaire entre crochets comme indiqué dans les exemples ci-dessus.


À propos de Java.time

Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent l'ancien héritage gênant classes date-heure telles que Java.util.Date , Calendar , & SimpleDateFormat .

Le projet Joda-Time , désormais en mode de maintenance , conseille la migration vers le Java.time Des classes.

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

Où obtenir les classes Java.time?

  • Java SE 8 , Java SE 9 et versions ultérieures
    • Intégré.
    • Fait partie de la norme Java avec une implémentation groupée.
    • Java 9 ajoute quelques fonctionnalités et correctifs mineurs.
  • Java SE 6 et Java SE 7
    • Une grande partie de la fonctionnalité Java.time est backportée vers Java 6 & 7 in ThreeTen-Backport .
  • Android
    • Versions ultérieures de Android bundle implementations of the Java.time (JSR 310) classes.
    • Pour les versions antérieures d'Android, le projet ThreeTenABP s'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 de futurs ajouts possibles à Java.time. Vous pouvez trouver ici des classes utiles telles que Interval , YearWeek , YearQuarter et plus .

4
Basil Bourque

Le problème est que CEST n'est pas un fuseau horaire Java prend en charge. Vous pouvez utiliser "CST".

Le Javadoc pour TimeZone note:

ID de fuseau horaire à trois lettres Pour la compatibilité avec JDK 1.1.x, certains autres ID de fuseau horaire à trois lettres (tels que "PST", "CTT", "AST") sont également pris en charge. Cependant, leur utilisation est déconseillée car la même abréviation est souvent utilisée pour plusieurs fuseaux horaires (par exemple, "CST" pourrait être US "Central Standard Time" et "China Standard Time"), et le = Java ne peut alors reconnaître qu'un seul d'entre eux.

Pour un support de fuseau horaire de trois/quatre lettres, je vous suggère d'essayer JodaTime qui peut faire un meilleur travail.


String dataRisposta = "Tue Jul 13 00:00:00 CST 2010";
Date dataRispostaDate = alfrescoDateFormat.parse(dataRisposta);
System.out.println(dataRispostaDate);

impressions

Tue Jul 13 07:00:00 BST 2010

String[] ids = TimeZone.getAvailableIDs();
Arrays.sort(ids);
for (String id : ids) {
    System.out.println(id);
}

impressions

...
CAT
CET
CNT
CST
CST6CDT
CTT
...
1
Peter Lawrey