2012-06-03 62 views
31

Ho bisogno di passare da millisecondi a una tupla di (ore, minuti, secondi, millisecondi) che rappresenta lo stesso intervallo di tempo. Ad esempio:Da millisecondi a ore, minuti, secondi e millisecondi

10799999ms = 2h 59m 59s 999ms

Il seguente pseudo-codice è l'unica cosa che ho potuto venire con:

# The division operator below returns the result as a rounded down integer 
function to_tuple(x): 
    h = x/(60*60*1000) 
    x = x - h*(60*60*1000) 
    m = x/(60*1000) 
    x = x - m*(60*1000) 
    s = x/1000 
    x = x - s*1000 
    return (h,m,s,x) 

Sono sicuro che deve essere possibile farlo più intelligente/più elegante/più veloce/più compatto.

+0

è possibile utilizzare l'operatore modulo (% in C e amici) per semplificare leggermente i calcoli di x (ad esempio x = x% (60 * 60 * 1000)) – fvu

+0

Assicurarsi di non disporre già di tale funzionalità nella libreria standard del linguaggio che si utilizza. –

risposta

83

Ecco come lo farei in Java:

int seconds = (int) (milliseconds/1000) % 60 ; 
int minutes = (int) ((milliseconds/(1000*60)) % 60); 
int hours = (int) ((milliseconds/(1000*60*60)) % 24); 
+2

vale la pena utilizzare TimeUnit in java per rendere il codice più leggibile. –

+8

'long millis = 12884983; System.out.println (((millis/(1000 * 60))% 60)); System.out.println (java.util.concurrent.TimeUnit.MILLISECONDS.toMinutes (millis)); output: 34 | 214 – JBoy

6

Buona domanda. Sì, lo si può fare in modo più efficiente. La tua CPU può estrarre sia il quoziente sia il resto del rapporto di due numeri interi in un'unica operazione. In <stdlib.h>, la funzione che espone questa operazione della CPU è denominata div(). Nella tua psuedocodarlo, utilizza qualcosa di simile:

function to_tuple(x): 
    qr = div(x, 1000) 
    ms = qr.rem 
    qr = div(qr.quot, 60) 
    s = qr.rem 
    qr = div(qr.quot, 60) 
    m = qr.rem 
    h = qr.quot 

Una risposta meno efficiente avrebbe utilizzato gli operatori / e % separatamente. Tuttavia, se è necessario sia il quoziente che il resto, in ogni caso, si potrebbe anche chiamare il più efficiente div().

4
non

davvero eleganter, ma un po 'più breve sarebbe

function to_tuple(x): 
    y = 60*60*1000 
    h = x/y 
    m = (x-(h*y))/(y/60) 
    s = (x-(h*y)-(m*(y/60)))/1000 
    mi = x-(h*y)-(m*(y/60))-(s*1000) 

    return (h,m,s,mi) 
5

Forse può essere più breve di un più elegante. Ma l'ho fatto.

public String getHumanTimeFormatFromMilliseconds(String millisecondS){ 
    String message = ""; 
    long milliseconds = Long.valueOf(millisecondS); 
    if (milliseconds >= 1000){ 
     int seconds = (int) (milliseconds/1000) % 60; 
     int minutes = (int) ((milliseconds/(1000 * 60)) % 60); 
     int hours = (int) ((milliseconds/(1000 * 60 * 60)) % 24); 
     int days = (int) (milliseconds/(1000 * 60 * 60 * 24)); 
     if((days == 0) && (hours != 0)){ 
      message = String.format("%d hours %d minutes %d seconds ago", hours, minutes, seconds); 
     }else if((hours == 0) && (minutes != 0)){ 
      message = String.format("%d minutes %d seconds ago", minutes, seconds); 
     }else if((days == 0) && (hours == 0) && (minutes == 0)){ 
      message = String.format("%d seconds ago", seconds); 
     }else{ 
      message = String.format("%d days %d hours %d minutes %d seconds ago", days, hours, minutes, seconds); 
     } 
    } else{ 
     message = "Less than a second ago."; 
    } 
    return message; 
} 
0
milliseconds = x 
total = 0 
while (milliseconds >= 1000) { 
    milliseconds = (milliseconds - 1000) 
    total = total + 1 
} 
hr = 0 
min = 0 
while (total >= 60) { 
    total = total - 60 
    min = min + 1 
    if (min >= 60) hr = hr + 1 
    if (min == 60) min = 0 
} 
sec = total 

Questo è il groove, ma io cosa che questo non è un problema per voi. Il metodo funziona perfettamente.

0
milliseconds = 12884983 // or x milliseconds 
hr = 0 
min = 0 
sec = 0 
day = 0 
while (milliseconds >= 1000) { 
    milliseconds = (milliseconds - 1000) 
    sec = sec + 1 
    if (sec >= 60) min = min + 1 
    if (sec == 60) sec = 0 
    if (min >= 60) hr = hr + 1 
    if (min == 60) min = 0 
    if (hr >= 24) { 
    hr = (hr - 24) 
    day = day + 1 
    } 
} 

spero che il mio metodo più breve vi aiuterà a

0
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.concurrent.TimeUnit; 

public class MyTest { 

    public static void main(String[] args) { 
     long seconds = 360000; 

     long days = TimeUnit.SECONDS.toDays(seconds); 
     long hours = TimeUnit.SECONDS.toHours(seconds - TimeUnit.DAYS.toSeconds(days)); 

     System.out.println("days: " + days); 
     System.out.println("hours: " + hours); 
    } 
} 
0

Arduino (C++) versione basata su Valentinos risposta

unsigned long timeNow = 0; 
unsigned long mSecInHour = 3600000; 
unsigned long TimeNow =0; 
int millisecs =0; 
int seconds = 0; 
byte minutes = 0; 
byte hours = 0; 

void setup() { 
Serial.begin(9600); 
Serial.println (""); // because arduino monitor gets confused with line 1 
Serial.println ("hours:minutes:seconds.milliseconds:"); 
} 

void loop() { 
TimeNow = millis(); 
hours = TimeNow/mSecInHour; 
minutes = (TimeNow-(hours*mSecInHour))/(mSecInHour/60); 
seconds = (TimeNow-(hours*mSecInHour)-(minutes*(mSecInHour/60)))/1000; 
millisecs = TimeNow-(hours*mSecInHour)-(minutes*(mSecInHour/60))-  (seconds*1000); 

Serial.print(hours); 
Serial.print(":"); 
Serial.print(minutes); 
Serial.print(":"); 
Serial.print(seconds); 
Serial.print("."); 
Serial.println(millisecs); 
} 
Problemi correlati