web-dev-qa-db-fra.com

Analyser la chaîne de date à certains Java Object

Je travaille dans un projet qui lit des fichiers et traite des données. Là, j'ai pu travailler avec des dates par exemple:

  1. 2012-01-10 23:13:26
  2. 13 janvier 2012

J'ai trouvé le package Joda, un package un peu intéressant mais je ne sais pas si c'est le plus simple.

J'ai pu analyser le premier exemple à un objet DateTime (Joda) reg-ex et manipulation de chaîne. (Ex: en remplaçant l'espace par '-' et en le passant au constructeur.

new DateTime("2012-01-10 23:13:26".replace(' ', '-'))

Je suppose que cela a fonctionné, mais le problème est avec le deuxième format. Comment puis-je utiliser une telle entrée pour extraire un objet, de préférence un objet Joda. Je peux certainement écrire une fonction pour changer le format sur ce que Joda prend en charge, mais je me demandais s'il y aurait une autre façon (même une bibliothèque native Java) de le faire.

S'il y a quelque chose de mieux que Joda, faites-le moi savoir.

Merci.

31
Ziyan Junaideen

En utilisant Joda-Time, jetez un œil à DateTimeFormat ; il permet d'analyser les deux types de chaînes de date que vous mentionnez (et presque tous les autres formats arbitraires). Si vos besoins sont encore plus complexes, essayez DateTimeFormatterBuilder .

Pour analyser # 1:

DateTimeFormatter f = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
DateTime dateTime = f.parseDateTime("2012-01-10 23:13:26");

Edit: effectivement LocalDateTime est un type plus approprié pour un datetime sans fuseau horaire:

LocalDateTime dateTime = f.parseLocalDateTime("2012-01-10 23:13:26");

Et pour # 2:

DateTimeFormatter f = DateTimeFormat.forPattern("MMMM dd, yyyy");
LocalDate localDate = f.parseLocalDate("January 13, 2012");

Et oui, Joda-Time est définitivement la voie à suivre, en ce qui concerne Java gestion de la date et de l'heure. :)

Comme presque tout le monde sera d'accord, Joda est une bibliothèque extrêmement conviviale. Par exemple, je n'avais jamais fait ce genre d'analyse avec Joda auparavant, mais il m'a fallu quelques minutes pour le comprendre à partir de l'API et l'écrire.

Mise à jour (2015)

Si vous êtes sur Java 8 , dans la plupart des cas, vous devez simplement utiliser Java.time au lieu de Joda-Time. Il contient à peu près toutes les bonnes choses - ou leurs équivalents - de Joda. Pour ceux qui connaissent déjà les API Joda, le guide de migration de Stephen Colebourne Joda-Time vers Java.time est très pratique.

Voici les versions Java.time des exemples ci-dessus.

Pour analyser # 1:

DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.from(f.parse("2012-01-10 23:13:26"));

Vous ne pouvez pas analyser ceci dans ZonedDateTime ou OffsetDateTime (qui sont des homologues de Joda's DateTime, utilisé dans ma réponse d'origine), mais cela a un peu de sens car il n'y a aucune information de fuseau horaire dans la chaîne analysée.

Pour analyser # 2:

DateTimeFormatter f = DateTimeFormatter.ofPattern("MMMM dd, yyyy");
LocalDate localDate = LocalDate.from(f.parse("January 13, 2012"));

Ici, LocalDate est le type le plus approprié pour analyser (comme avec Joda-Time).

39
Jonik

SimpleDateFormat analysera les dates dans Java Objets date:

http://docs.Oracle.com/javase/1.4.2/docs/api/Java/text/SimpleDateFormat.html

SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); // first example
SimpleDateFormat format2 = new SimpleDateFormat("MMMMM dd,yyyy"); // second example

Date d1 = format1.parse( dateStr1 );
Date d2 = format2.parse( dateStr2 );
23
chubbsondubs

J'imagine que Joda a quelque chose d'un formateur pour le faire pour vous. J'ai trouvé cela avec une recherche rapide sur Google: http://johannburkard.de/blog/programming/Java/date-time-parsing-formatting-joda-time.html

DateTimeFormatter parser1 =
    DateTimeFormat.forPattern("dd/MMM/yyyy:HH:mm:ss Z");

DateTimeFormatter parser2 =
    DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");

DateTime time = parser1.parseDateTime("<data>");

La syntaxe utilisée pour évaluer les modèles se trouve dans lien de X-Zero .

7
nicholas.hauschild

JodaTime est largement considéré comme la norme de facto pour le traitement date-heure dans Java - ils travaillent pour l'ajouter à la prochaine version du Java bibliothèque (enfin, efficacement).

Pour obtenir des dates JodaTime à partir de chaînes, vous allez vouloir examiner la classe DateTimeFormat .

5
Clockwork-Muse

Le plus simple serait de configurer SimpleDateFormat correctement selon le format que vous attendez et d'utiliser sa méthode d'analyse pour vous donner un objet Date

2
rakche

tl; dr

LocalDateTime ldt = LocalDateTime.parse( "2012-01-10 23:13:26".replace( " " , "T" ) );

…et…

LocalDate localDate = LocalDate.parse ( "January 13, 2012" , DateTimeFormatter.ofLocalizedDate ( FormatStyle.LONG ).withLocale ( Locale.US ) );

Détails

Réponse de Jonik est fondamentalement correct mais manque quelques problèmes importants.

Java.time

S'il y a quelque chose de mieux que Joda, faites-le moi savoir.

Oui, il y a quelque chose de mieux, le framework Java.time . L'équipe Joda-Time conseille la migration vers Java.time en tant que successeur.

Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes classes de date-heure gênantes telles que Java.util.Date, .Calendar, & Java.text.SimpleDateFormat.

Pour en savoir plus, consultez le Oracle Tutorial . Et recherchez Stack Overflow pour de nombreux exemples et explications.

Une grande partie de la fonctionnalité Java.time est back-portée vers Java 6 & 7 in ThreeTen-Backport et plus adaptée à Android dans ThreeTenABP .

Date-heure

Votre première entrée est une date plus une heure du jour. Il manque --- offset-from-UTC ou fuseau horaire info, donc nous l'analysons comme un objet LocalDateTime . Le "Local…" signifie toute localité , aucune localité spécifique. Ce n'est donc pas un moment réel sur la chronologie mais plutôt juste une idée approximative d'un moment.

Pour analyser la chaîne d'entrée 2012-01-10 23:13:26 nous pouvons remplacer l'ESPACE au milieu par un T pour nous conformer au style canonique pour le format standard ISO 8601 des valeurs date-heure.

Les classes Java.time utilisent par défaut les formats ISO 8601 lors de l'analyse et de la génération de représentations textuelles des valeurs date-heure. Il n'est donc pas nécessaire de définir un modèle d'analyse.

String input = "2012-01-10 23:13:26".replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( input );

Si vous connaissez le fuseau horaire prévu dans le contexte de cette valeur, appliquez-le pour définir un moment réel sur la chronologie.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zoneId );

Dump sur console.

System.out.println ( "input: " + input + " | zdt: " + zdt );

entrée: 2012-01-10T23: 13: 26 | zdt: 2012-01-10T23: 13: 26-05: 00 [Amérique/Montréal]

Date uniquement

La seconde d'entre vous est une valeur de date uniquement sans heure et sans fuseau horaire. Pour cela, nous avons besoin de la classe LocalDate .

Je reconnais que le format de cette entrée est conforme à la langue (anglais) et aux normes culturelles des États-Unis. Il n'est donc pas nécessaire de spécifier explicitement un modèle de formatage. Nous pouvons simplement demander un formateur qui connaît ce format US en spécifiant un Locale . Nous spécifions FormatStyle.LONG selon la longueur de ce format.

String input = "January 13, 2012";
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate ( FormatStyle.LONG ).withLocale ( Locale.US );
LocalDate localDate = LocalDate.parse ( input , formatter );

Dump sur console.

System.out.println ( "input: " + input + " | localDate: " + localDate );

entrée: 13 janvier 2012 | localDate: 2012-01-13

1
Basil Bourque