web-dev-qa-db-fra.com

Comment convertir HH: mm: ss.SSS en millisecondes?

J'ai une chaîne 00:01:30.500 ce qui équivaut à 90500 millisecondes. J'ai essayé d'utiliser SimpleDateFormat qui donne des millisecondes, y compris la date actuelle. J'ai juste besoin de cette représentation String en millisecondes. Dois-je écrire une méthode personnalisée qui divisera et calculera les millisecondes? ou Y a-t-il une autre façon de procéder? Merci.

J'ai essayé comme suit:

        String startAfter = "00:01:30.555";
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
        Date date = dateFormat.parse(startAfter);
        System.out.println(date.getTime());
18
Ahamed

Vous pouvez utiliser SimpleDateFormat pour le faire. Il suffit de savoir 2 choses.

  1. Toutes les dates sont représentées en interne en UTC
  2. .getTime() renvoie le nombre de millisecondes depuis 1970-01-01 00:00:00 UTC.
package se.wederbrand.milliseconds;

import Java.text.SimpleDateFormat;
import Java.util.Date;
import Java.util.TimeZone;

public class Main {        
    public static void main(String[] args) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

        String inputString = "00:01:30.500";

        Date date = sdf.parse("1970-01-01 " + inputString);
        System.out.println("in milliseconds: " + date.getTime());        
    }
}
36
Andreas Wederbrand

Si vous souhaitez analyser le format vous-même, vous pouvez le faire facilement avec une expression régulière telle que

private static Pattern pattern = Pattern.compile("(\\d{2}):(\\d{2}):(\\d{2}).(\\d{3})");

public static long dateParseRegExp(String period) {
    Matcher matcher = pattern.matcher(period);
    if (matcher.matches()) {
        return Long.parseLong(matcher.group(1)) * 3600000L 
            + Long.parseLong(matcher.group(2)) * 60000 
            + Long.parseLong(matcher.group(3)) * 1000 
            + Long.parseLong(matcher.group(4)); 
    } else {
        throw new IllegalArgumentException("Invalid format " + period);
    }
}

Cependant, cette analyse est assez clémente et accepterait 99: 99: 99.999 et laisserait les valeurs déborder. Cela pourrait être un inconvénient ou une fonctionnalité.

6
Roger Lindsjö

Si vous souhaitez utiliser SimpleDateFormat, vous pouvez écrire:

private final SimpleDateFormat sdf =
    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    { sdf.setTimeZone(TimeZone.getTimeZone("GMT")); }

private long parseTimeToMillis(final String time) throws ParseException
    { return sdf.parse("1970-01-01 " + time).getTime(); }

Mais une méthode personnalisée serait beaucoup plus efficace. SimpleDateFormat, en raison de toute sa prise en charge du calendrier, de la prise en charge des fuseaux horaires, de la prise en charge de l'heure d'été, etc., est assez lente. La lenteur en vaut la peine si vous avez réellement besoin de certaines de ces fonctionnalités, mais comme vous ne l'avez pas, ce n'est peut-être pas le cas. (Cela dépend de la fréquence à laquelle vous appelez cette méthode et de l'efficacité de votre application.)

De plus, SimpleDateFormat n'est pas compatible avec les threads, ce qui est parfois pénible. (Sans rien savoir de votre candidature, je ne peux pas deviner si cela importe.)

Personnellement, j'écrirais probablement une méthode personnalisée.

2
ruakh

Utilisation de JODA :

PeriodFormatter periodFormat = new PeriodFormatterBuilder()
  .minimumParsedDigits(2)
  .appendHour() // 2 digits minimum
  .appendSeparator(":")
  .minimumParsedDigits(2)
  .appendMinute() // 2 digits minimum
  .appendSeparator(":")
  .minimumParsedDigits(2)
  .appendSecond()
  .appendSeparator(".")
  .appendMillis3Digit()
  .toFormatter();
Period result = Period.parse(string, periodFormat);
return result.toStandardDuration().getMillis();
2
Louis Wasserman