2009-08-21 8 views
10

Je me gratte vraiment la tête sur celui-ci. J'ai utilisé SimpleDateFormat s sans aucun problème pendant un moment, mais maintenant, en utilisant un SimpleDateFormat pour analyser les dates est (seulement parfois) tout simplement faux.Analyse de date incohérente en utilisant SimpleDateFormat

Plus précisément:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
Date date = sdf.parse("2009-08-19 12:00:00"); 
System.out.print(date.toString()); 

imprime la chaîne Wed Aug 19 00:00:00 EDT 2009. Que diable? - Il n'analyse même pas la mauvaise date tout le temps!


Mise à jour: Ce fixe magnifiquement. Ne le saviez-vous pas, cela a été mal utilisé dans quelques autres endroits aussi. Doit aimer déboguer le code d'autres personnes :)

+3

J'aimerais que les gens cessent d'appeler les choses «bizarres» et «bizarres» quand ils font des erreurs. :/ – Bombe

+0

Désolé. Je déboguais du code que quelqu'un de mes nombreuses années avait écrit, et je m'attendais à pouvoir faire confiance. –

Répondre

25

Je pense que vous voulez utiliser le format HH, plutôt que « hh » de sorte que vous utilisez heures entre 00-23. 'hh' prend le format par incréments de 12 heures, et donc il suppose qu'il est dans le matin.

Donc, ce

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
Date date = sdf.parse("2009-08-19 12:00:00"); 
System.out.print(date.toString()); 

Si imprimer

Mer 19 août 12:00:00 EDT 2009

2

Vous imprimez la représentation toString() de la date, plutôt que la représentation du format. Vous pouvez également vérifier la représentation de l'heure. H et h signifient quelque chose de différent. H est pour l'horloge de 24 heures (0-23), h pour l'horloge de 12 heures (1-12), (il y a aussi k et K pour 1-24 et 0-11 fois respectivement)

Vous besoin de faire quelque chose comme:

//in reality obtain the date from elsewhere, e.g. new Date() 
Date date = sdf.parse("2009-08-19 12:00:00"); 

//this format uses 12 hours for time 
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
//this format uses 24 hours for time 
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

System.out.print(sdf.format(date)); 
System.out.print(sdf2.format(date)); 
+0

Je vais essayer, mais je ne pense pas que ça va résoudre le problème. Dans mon application, je ne suis pas en train de convertir en chaîne. J'enregistre la date dans une base de données, et c'est faux là aussi. –

+0

Vos chaînes de format sont-elles cohérentes? Certains SGBD convertissent automatiquement les valeurs s'ils peuvent comprendre les choses, d'autres non. Les valeurs problématiques dans une ou plusieurs colonnes avec un formatage différent sont-elles appliquées au niveau db? Ou provenant d'une connexion dont les paramètres sont différents? – DaveE

1

tl; dr

LocalDateTime ldt = LocalDateTime.parse("2009-08-19 12:00:00".replace(" " , "T")); 

java.time

D'autres réponses sont correctes, mais utiliser des classes date temps anciens. Ces anciennes classes gênantes ont été supplantées par les classes java.time.

Votre chaîne d'entrée est proche du format standard ISO 8601. Tweak en remplaçant l'espace au milieu avec un T. Ensuite, il peut être analysé sans spécifier de modèle de formatage. Les classes java.time utilisent ISO 8601 par défaut lors de l'analyse/génération de chaînes. Les données d'entrée n'a aucune information sur offset-from-UTC ou le fuseau horaire. Nous analysons donc comme LocalDateTime.

LocalDateTime ldt = LocalDateTime.parse(input); 

Si le contexte vous indique le décalage souhaité, appliquez-le. Peut-être qu'il était destiné à UTC (un décalage de zéro), où nous pouvons utiliser la constante ZoneOffset.UTC.

OffsetDateTime odt = ldt.atOffset(ZoneOffset.UTC); 

Ou peut-être savez-vous qu'il était destiné à un fuseau horaire particulier. Un fuseau horaire est un décalage plus un ensemble de règles pour gérer les anomalies telles que l'heure d'été (DST).

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

A propos java.time

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

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

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

Une grande partie de la fonctionnalité de java.time est à nouveau porté à Java-6 & 7 dans ThreeTen-Backport et en outre adapté pour Android en ThreeTenABP (voir How to use…).

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.