Contexte:
Dans ma table de base de données, j'ai deux horodatages
timeStamp1 = 2011-08-23 14:57:26.662
timeStamp2 = 2011-08-23 14:57:26.9
Lorsque je fais un "ORDER BY TIMESTAMP ASC", timeStamp2 est considéré comme le plus grand horodatage (ce qui est correct).
Exigence: J'ai besoin d'obtenir la différence de ces horodatages (timeStamp2 - timeStamp1)
Mon implémentation:
public static String timeDifference(String now, String prev) {
try {
final Date currentParsed = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(now);
final Date previousParsed = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(prev);
long difference = currentParsed.getTime() - previousParsed.getTime();
return "" + difference;
} catch (ParseException e) {
return "Unknown";
}
}
La réponse aurait dû être de 238 ms, mais la valeur renvoyée est -653 ms. Je ne suis pas sûr de ce que je fais mal. Aucune suggestion?
Je ne suis pas tout à fait sûr, mais le JavaDoc déclare ceci:
Pour l'analyse, le nombre de lettres de modèle est ignoré sauf s'il est nécessaire de séparer deux champs adjacents.
Cela indique que les millisecondes de 2011-08-23 14:57:26.9
serait analysé comme 9
au lieu de 900
. L'ajout de zéros de fin peut fonctionner: 2011-08-23 14:57:26.900
.
Le format que vous analysez et le format utilisé ne correspondent pas. Vous vous attendez à un champ à trois chiffres et ne fournissez qu'un seul chiffre. Ça prend 9
et suppose que vous voulez dire 009
quand ce que vous voulez c'est 900
. Les formats de date sont compliqués et lorsque vous prouvez des dates dans un format différent, cela peut les analyser différemment.
La documentation indique que S
signifie le nombre de millisecondes et le nombre dans ce champ est 9, donc il se comporte correctement.
EDIT: Cet exemple peut aider
final SimpleDateFormat ss_SSS = new SimpleDateFormat("ss.SSS");
ss_SSS.setTimeZone(TimeZone.getTimeZone("GMT"));
for (String text : "0.9, 0.456, 0.123456".split(", ")) {
System.out.println(text + " parsed as \"ss.SSS\" is "
+ ss_SSS.parse(text).getTime() + " millis");
}
impressions
0.9 parsed as "ss.SSS" is 9 millis
0.456 parsed as "ss.SSS" is 456 millis
0.123456 parsed as "ss.SSS" is 123456 millis
J'ai eu le même problème avec l'heure trop précise de mes fichiers journaux avec 6 millisecondes numériques. Le temps d'analyse a donné jusqu'à 16 minutes de différence! WTF?
16-JAN-12 04.00.00.999999 PM GMT --> 16 Jan 2012 04:16:39 GMT
Changer le nombre de chiffres a réduit la différence erronée et grâce à ce fil, j'ai pu identifier le problème:
16-JAN-12 04.00.00.99999 PM GMT --> 16 Jan 2012 04:01:39 GMT
16-JAN-12 04.00.00.9999 PM GMT --> 16 Jan 2012 04:00:09 GMT
16-JAN-12 04.00.00.999 PM GMT --> 16 Jan 2012 04:00:00 GMT
Comme SimpleDateFormat
ne gère en interne que 3 chiffres, j'ai supprimé l'inutile avec une petite expression régulière (en ignorant les erreurs d'arrondi, en travaillant de 1 à n chiffres):
str = str.replaceAll("(\\.[0-9]{3})[0-9]*( [AP]M)", "$1$2");
Merci à @Peter Lawrey pour votre réponse, ça m'a empêché de devenir fou :-)
Je suggère d'utiliser Joda-Time . Il gère ces situations correctement. Dans l'exemple suivant, les millisecondes sont correctement analysées comme 200 ms.
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class ParseMillis {
public static void main(String[] args) {
String s = "00:00:01.2";
DateTimeFormatter format = DateTimeFormat.forPattern("HH:mm:ss.S");
DateTime dateTime = format.parseDateTime(s);
System.out.println(dateTime.getMillisOfSecond());
}
}