Formatta i microsecondi come ore: minuti: secondi, ecc


28

Quanto segue è ispirato da una domanda che è stata posta oggi su Stack Overflow .

Dato un numero di microsecondi, 0 <= n <= 86400000000(ad es. 12345678900), Emette una stringa formattata hh:mm:ss:000:000, ad es 03:25:45:678:900.

          0 -> '00:00:00:000:000'
12345678900 -> '03:25:45:678:900'
86400000000 -> '24:00:00:000:000'

Ho una soluzione in Python in 209 byte, ma può andare più in basso?


1
Ora mi rendo conto che questo non è davvero un formato standard per i tempi di scrittura e hh:mm:ss.000000probabilmente sarebbe stato migliore (e più semplice). Tuttavia, non posso cambiarlo ora.
Sam,

1
Per curiosità, qual era il post SO?
Trauma digitale

@DigitalTrauma stackoverflow.com/questions/31251377 da un relativamente nuovo utente. Era già stata scelta una risposta corretta, stavo solo giocando in IDLE e ho trovato una comprensione del dizionario dall'aspetto grottesco che non era una risposta particolarmente buona alla domanda. Qualcuno l'ha visto e ha sottolineato questo sito in un commento. Sono venuto qui, ho scritto una domanda (leggermente diversa dal post SO) e ho anche scritto una versione molto migliorata della mia risposta (che non ho pubblicato e che ora è ridondante a tutte le risposte molto più compatte e fantasiose di seguito) .
Sam

C'è un limite al numero di ore nell'input?
FUZxxl,

Sì, arbitrariamente l'ho reso <= 86400000000 microsec, quindi <= 24 ore.
Sam

Risposte:


15

Python 2, 82 79 byte

n=input()
o=""
for k in[1000]*2+[60]*3:o=":%0*d"%(k%7/2,n%k)+o;n/=k
print o[1:]

Costruisce la stringa, ripetendo una serie di divmods. L'unico pezzo di fantasia è il %7/2, che mappa 1000 -> 3e 60 -> 2.


6

Pyth, 31 byte

j\:_m>l`td+"00"%~/QddCM"ϨϨ<<<

Provalo online: dimostrazione

Spiegazione:

                                 implicit: Q = input number
                       "ϨϨ<<<   string "ϨϨ<<<" (5 chars but 7 bytes)
                     CM          convert each to number => [1000, 1000, 60, 60, 60]
    m                            map each number d to:
                 /Qd                divide Q by d
                ~                   and update Q with the new value
               %~ Q d               but use the old value to calculate Q mod d
          +"00"                     add the result to the string "00"
     >                              but only take the last 
      l`td                          len(str(d-1)) chars
   _                             revert order
j\:                              join the strings with ":"s

5

Bash + coreutils, 61

La lingua "mainstream" più corta finora ...

a=%02d:
printf $a$a$a%03d:%03d `dc -e$1\ A00~rA00~r60~r60~rf`

Uscita di prova:

$ for t in 0 12345678900 86400000000; do ./usec.sh $t; echo; done
00:00:00:000:000
03:25:45:678:900
24:00:00:000:000
$ 

4

CJam, 37 35 34 byte

Questo è abbastanza lungo .. Giocare a golf ora ..

ri[1e3_60__]{:ImdsIBb,0e[':@}%W%2>

AGGIORNAMENTO: 1 byte salvato grazie a @ Sp3000

Provalo online qui


4

C, 97 byte

q=1000,s=60;
#define f(n)printf("%02d:%02d:%02d:%03d:%03d",n/s/s/q/q,n/s/q/q%s,n/q/q%s,n/q%q,n%q)

Codice test:

int main(int intc, char **argv)
{
    long long n = atoll(argv[1]);
    f(n);
}

1
Le risposte in C dovrebbero essere un programma completo; non uno snippet.
NobodyNada - Ripristina Monica il

Non è menzionato nella domanda. Esiste una sorta di requisiti globali?
alcuni utenti il


No. Se leggi la risposta, usa semplicemente C come esempio. La regola si sarebbe applicata ad ogni lingua. Inoltre, la risposta è fortemente contestata: vedi il commento più votato. La linea di fondo è che la domanda deve dichiarare chiaramente se è necessario un programma completo.
alcuni utenti il

3
Molte risposte su questo sito usano funzioni invece di programmi completi - per esempio non penso di aver mai visto una risposta Java che fosse un programma completo ...
Jerry Jeremiah,

4

q (34)

Sono sicuro che può essere più breve

":"sv 0 8 11__[;8]15$2_($)16h$1e3*

per esempio

q)f:":"sv 0 8 11__[;8]15$2_($)16h$1e3*
q)f 12345678900
"03:25:45:678:900"

4
qualche compilatore online? in altre parole: come lo eseguo come una persona pigra?
Ottimizzatore

La versione a 32 bit è disponibile gratuitamente su kx.com
skeevey il

buon posto. sfortunatamente la correzione aggiunge alcuni personaggi
skeevey

1
puoi tagliare più byte qui":"sv 0 8 11__[;8]15$2_($)"n"$1e3*
WooiKent Lee

3

Julia, 110 96 95 byte

t->(o="";for i=int([36e8,6e7,1e6,1e3,1]) x,t=t÷i,t%i;o*=lpad(x,i>1e3?2:3,0)*":"end;o[1:end-1])

Ciò crea una funzione senza nome che accetta un numero intero come input e restituisce una stringa. Per chiamarlo, dagli un nome, ad es f=t->....

Ungolfed + spiegazione:

function f(t)
    # Initialize an output string
    o = ""

    # Loop over an array consisting of the number of microseconds in
    # an hour, minute, second, millisecond, and microsecond
    for i = int([36e8, 6e7, 1e6, 1e3, 1])

        # Get the quotient and remainder for microseconds into t,
        # setting t to be the remainder
        x, t = t ÷ i, t % i

        # Left-pad x with zeroes and append it to the output
        o *= lpad(x, i > 1e3 ? 2 : 3, 0) * ":"
    end

    # o has a trailing :, so return everything but the last character
    o[1:end-1]
end

Esempi:

julia> f(12345678900)
"03:25:45:678:900"

julia> f(0)
"00:00:00:000:000"

julia> f(86400000000)
"24:00:00:000:000"

Ben fatto. Ottieni il mio voto perché hai ispirato la mia risposta a Matlab :-)
Hoki,

3

C #, 179 175 byte

Quando hai builtin a tua disposizione, perché non usarli?

static void Main(string[]a){var t=TimeSpan.FromTicks(long.Parse(Console.ReadLine())*10);Console.Write(t.ToString((t.Days<1?"hh":@"\2\4")+@"\:mm\:ss\:ffffff").Insert(12,":"));}

Con una migliore formattazione:

static void Main(string[]a){
    var t = TimeSpan.FromTicks(long.Parse(Console.ReadLine())*10);
    Console.Write(t.ToString((t.Days<1?"hh":@"\2\4")+@"\:mm\:ss\:ffffff").Insert(12,":"));
    Console.Read();
}

3

Excel, 65 63 caratteri

Supponendo che i tuoi microsecondi siano in A1 :

=TEXT(A1/50/1200^3,"[HH]:mm:ss:")&RIGHT(TEXT(A1,"000\:000"),7)

Produzione:

        A              B
1            0  00:00:00:000:000
2  12345678900  03:25:46:678:900
3  86400000000  24:00:00:000:000

2

Perl, 141 78 byte

printf"%02d"x3.%03d:%03d",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_‌​%1e3

77 byte di codice, +1 per la -nbandiera. Corri con:

echo 12345678900 | perl -ne'printf"%02d"x3.%03d:%03d",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_‌​%1e3'

Grazie a Thomas Kwa e chilemagic per aver ridotto la mia dimensione del codice quasi a metà.


Penso che 3600000000possa essere 36e8.
lirtosiast,

Invece di chomp($n=<STDIN>);te puoi eseguirlo come una linea con la -nbandiera (che conta come 1 carattere). Inoltre non è necessario il int(..)giro ciascuno $_. Applicando anche il suggerimento di Thomas, possiamo ottenerlo echo 12345678900 | perl -ne'printf"%02d:%02d:%02d:%03d:%03d\n",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_%1e3'e potrebbe esserci anche un modo più breve!
hmatt1,

Neanche \nnella stringa di output è necessario. Puoi anche sostituire la stringa con"%02d:"x3 ."%03d:%03d"
hmatt1

@chilemagic L'uso di "echo" conta come un aumento di byte?
ASCIIThenANSI

@ASCIIThenANSI non lo fa perché non fa parte del tuo programma. I caratteri che dovresti contare sono quelli tra le virgolette singole, cioè printf"%02d:%02d:%02d:%03d:%03d\n",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_‌​%1e3e quindi aggiungi un byte aggiuntivo per il -nflag. Se lo hai usato, -nlead esempio, sarebbe conteggiato come un ulteriore 2 (per il ne il l). Ottieni il -e il e(o Ese devi usarlo say) gratuitamente.
hmatt1,

1

Matlab - 88 89 byte

Ottenuto un byte con una soluzione senza utilizzare la funzione integrata:

n=[36e8,6e7,1e6,1e3];f=@(t)sprintf('%02d:%02d:%02d:%03d:%03d',fix([t mod(t,n)]./[n 1]))

Creare una funzione incorporata che accetta un argomento di input numerico te restituisce una stringa.

utilizza una combinazione vettoriale di fixe modper separare gli elementi del tempo, quindi visualizzare.

è un po 'frustrante che la formattazione della stringa di output richieda molto, più dei calcoli stessi ...

Test:

for t=[0 12345678900 86400000000]
    f(t)
end

ans =
00:00:00:000:000
ans =
03:25:45:678:900
ans =
24:00:00:000:000

89 byte versione:

f=@(t)sprintf('%s:%03d:%03d',datestr(fix(t/1e6)/86400,13),fix(mod(t,1e6)/1e3),mod(t,1e3))

Suddivide il numero, utilizza una funzione integrata per la parte hh: mm: ss, che non può gestire i microsecondi, quindi la stringa viene completata con la combinazione di fixe modoperazioni


1

JavaScript (ES6), 128 118 116 111 byte

C'è probabilmente un potenziale di golf in questo.

f=t=>(t<864e8?new Date(t/1e3).toJSON().slice(11,-1):`24:00:00:000`).replace(`.`,`:`)+':'+('00'+t%1e3).slice(-3)

dimostrazione

È ES6 quindi solo Firefox, per ora comunque:

f=t=>(t<864e8?new Date(t/1e3).toJSON().slice(11,-1):`24:00:00:000`).replace(`.`,`:`)+':'+('00'+t%1e3).slice(-3)

// DEMO
document.body.innerHTML += '<br>' + f(0);
document.body.innerHTML += '<br>' + f(12345678020);
document.body.innerHTML += '<br>' + f(86400000000);


Il primo controllo non è necessario, poiché la domanda è esplicita: 0 <= n <= 86400000000
edc65

@ edc65 Senza il primo controllo posso ottenere solo un intervallo di 0 ≤ n <86400000000, poiché 8.64e10 passerebbe al giorno successivo.
rink.attendant.6

Oh giusto, l'ho perso. toJSON () anziché toISOString ()?
edc65,

1

C, 113 103 105 105 byte

EDIT: rimosso da qualche altro byte

FIX: rimosso tipo lungo, grazie ad alcuni utenti

Non è la risposta C più breve, ma mi sono divertito un po 'con i ritorni a capo, quindi mi è sembrato che qualcuno potesse apprezzare questo.

i,k,p=16;
#define f(n)for(;i<5;p-=i++<2?4:3)k=i<2?1000:60,printf("%0*d%c\r",p,n%k,i?58:13),n/=k;puts("");

Chiamalo come:

int main() {
    long long n = 12345678900;
    f(n);

    return 0;
}

Dipende dalla piattaforma, "long" potrebbe essere solo a 32 bit. (vedi en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models ). Ho evitato il problema dichiarando "f" come macro anziché come funzione.
alcuni utenti il

Ho notato che. Ho assunto GCC su x64, riparandolo domani.
Andrea Biondo,

0

CoffeeScript, 127 byte

Ha preso l'approccio nella risposta di ASCIIThenANSI . È un peccato che l' API della console JavaScript non abbia segnaposto di formato per i numeri di riempimento.

p=(a,b)->('00'+~~a).slice -b||-2
f=(t)->console.log '%s:%s:%s:%s:%s',p(t/36e8),p(t/6e7%60),p(t/1e6%60),p(t/1e3%1e3,3),p t%1e3,3

0

PowerShell, 153

$t=[timespan]::FromTicks(($a=$args[0]));"{0:D2}:{1:D2}:{2:D2}:{3:D3}:{4:000}"-f
[int]($t.TotalHours),$t.Minutes,$t.Seconds,$t.Milliseconds,(($a%1e4)/10)

uso

powershell -nologo .\modprintsec.ps1 123456789000    
03:25:45:678:900   
powershell -nologo .\modprintsec.ps1 864000000000   
24:00:00:000:000   
powershell -nologo .\modprintsec.ps1 0   
00:00:00:000:000 

0

F #, 111 92 102 byte

Prima iterazione: idea di base.

Seconda iterazione: costanti più piccole

Terza iterazione: formattazione corretta per porzioni a una cifra.

Nota questa funzione deve avere un int64 per funzionare.

let s,t=60L,1000L
let f n=sprintf"%02d:%02d:%02d:%03d:%03d"(n/s/s/t/t)(n/s/t/t%s)(n/t/t%s)(n/t%t)(n%t)

Esempi di output:

f 0L           -> "00:00:00:000:000"
f 12345678900L -> "03:25:45:678:900"
f 86400000000L -> "24:00:00:000:000"

0

PHP - 115 102 byte

Una soluzione in 155 byte (racchiusa qui su 3 righe per leggibilità):

$a=$argv[1];
$h=($a-($m=($a=($a-($s=($a=($a-($t=($a=($a-($u=$a%1000))/1000)%1000))/1000)%60))/60)%60))/60;
printf("%02d:%02d:%02d:%03d:%03d",$h,$m,$s,$t,$u);

La seconda riga calcola (dall'interno verso l'esterno) i valori esatti dei componenti a partire dai microsecondi.

La versione più corta (115 byte, racchiusa in due righe per la leggibilità):

$u=$argv[1];$h=($m=($s=($t=$u/1000)/1000)/60)/60;
printf("%02d:%02d:%02d:%03d:%03d",$h,$m%60,$s%60,$t%1000,$u%1000);

Utilizza anche le assegnazioni incorporate per calcolare la conversione del numero di input di microsecondi in millisecondi, secondi, minuti e ore utilizzando numeri in virgola mobile. L'operatore modulo ( %) e il formato numerico decimale ( %d) di printf()vengono quindi utilizzati per forzarli a numeri interi (la parte frazionaria viene ignorata).

Un'altra soluzione che utilizza le funzioni di data (102 byte)

$u=$argv[1];
echo gmdate("H:i:s",strtotime("@".substr($u,0,-6))),":",substr($u,-6,3),":",substr($u,-3);

Le ore: minuti: la parte dei secondi è gestita dalle funzioni della data di PHP gmdate()e strtotime(), i milli e i micro-secondi vengono estratti come stringhe dal valore di input.

Uso:

$ php -r '$u=$argv[1];echo gmdate("H:i:s",strtotime("@".substr($u,0,-6))),":",substr($u,-6,3),":",substr($u,-3);' 7198898787; echo
01:59:58:898:787

0

Java, 215 byte

String f(long n){return p(n/3600000000l,2)+":"+p(n/60000000%60,2)+":"+p(n/1000000%60,2)+":"+p(n/1000%1000,3)+":"+p(n%1000,3);}String p(long n,int i){String s=String.valueOf(n);while(s.length()<i){s="0"+s;}return s;}

Il metodo fesegue alcuni calcoli per calcolare nle ore, i minuti, ecc. E delega al metodo pper formattare correttamente ciascun valore.

formattato:

String f(long n) {
    return p(n / 3600000000l, 2) + ":" + p(n / 60000000 % 60, 2) + ":" 
            + p(n / 1000000 % 60, 2) + ":" + p(n / 1000 % 1000, 3) + ":" + p(n % 1000, 3);
}

String p(long n, int i) {
    String s = String.valueOf(n);
    while (s.length() < i) {
        s = "0" + s;
    }
    return s;
}

Uso:

public void demo() {
    long n = 12345678900l;
    System.out.println(f(n));
}

-1

Rubino - 82 byte

puts (t=Time.at(0,gets.to_i)).strftime("%2H:%2M:%2S:%3L:#{(t.usec%1000).to_s.rjust(3,?0)}")

2
Ma ho contato 91 byte. Funziona anche solo nel fuso orario UTC.
jimmy23013,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.