2012-01-11 19 views
15

Ho una stringa 00:01:30.500 che equivale a 90500 millisecondi. Ho provato a utilizzare SimpleDateFormat che danno millisecondi compresa la data corrente. Ho solo bisogno di quella rappresentazione String in millisecondi. Devo scrivere un metodo personalizzato, che dividerà e calcolerà millisecondi? o c'è qualche altro modo per farlo? Grazie.Come convertire HH: mm: ss.SSS in millisecondi?

ho provato come segue:

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

Quale motivo hai utilizzato per creare SimpleDateFormat? Puoi pubblicare il codice? –

risposta

31

È possibile utilizzare SimpleDateFormat per farlo. Devi solo sapere 2 cose.

  1. Tutte le date sono rappresentati internamente in UTC
  2. .getTime() restituisce il numero di millisecondi dal 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());   
    } 
} 
+1

Non c'è bisogno di anteporre yyyy-MM-dd e 1970-01-01. Analizzando come l'OP ha funzionato se il fuso orario è impostato su GMT. –

+0

@JBNizet true e un buon punto. Ho incluso volutamente le informazioni sulla data extra perché penso che mostri meglio cosa sta realmente accadendo. –

+0

@AndreasWederbrand: Il "trucco" che fa funzionare qui è quello di impostare il giorno al 1 ° gennaio 1970. Ma supponiamo che se non lo dessi oggi, funzionerà? –

2

Se si desidera utilizzare SimpleDateFormat, si potrebbe scrivere:

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(); } 

Ma un metodo personalizzato sarebbe molto più efficiente. SimpleDateFormat, a causa di tutto il supporto del calendario, il supporto per fuso orario, il supporto per l'ora legale e così via, è piuttosto lento. La lentezza vale la pena se hai effettivamente bisogno di alcune di queste funzionalità, ma dal momento che non lo fai, potrebbe non esserlo. (Dipende dalla frequenza con cui si chiama questo metodo e dal fatto che l'efficienza sia un problema per l'applicazione.)

Inoltre, è non protetto da thread, il che a volte è un problema. (Senza sapere nulla della tua domanda, non riesco a indovinare se è importante.)

Personalmente, probabilmente scriverei un metodo personalizzato.

+0

Non è necessario anteporre yyyy-MM-dd e 1970-01-01. Analizzando come l'OP ha funzionato se il fuso orario è impostato su GMT. –

+0

@JBNizet: Sul mio sistema è vero, ma l'OP ha scritto che il suo approccio ha dato "millisecondi inclusa la data corrente", quindi presumevo che l'implementazione del suo JDK di 'SimpleDateFormat' non potesse chiamare' calendar.clear () '. Non vedo nulla nel Javadoc che indica che 'SimpleDateFormat' deve essere impostato su 1970-01-01. Sai se è garantito? – ruakh

1

Utilizzando 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(); 
3

Se si vuole analizzare il formato da soli si potrebbe fare facilmente con un espressione regolare come

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); 
    } 
} 

Tuttavia, questa analisi è abbastanza indulgente e accetterebbe 99 : 99: 99.999 e lascia che i valori trabocchino. Questo potrebbe essere un inconveniente o una caratteristica.

+0

Hey Ho usato il vostro approccio ma dà il risultato con un valore aggiunto - tra carattere, è questo a causa di L è stato utilizzato con 3600000 – Prateek

+0

Probabilmente no, la L è quello di renderlo un lungo. Quale parte dà il risultato con un -? Il dateParseRegExp restituisce un lungo che non ha una - (a meno che non è negativo). È uno dei gruppi corrispondenti che ha il -? –

+0

OOPS non a causa di L mio male. – Prateek

Problemi correlati