Formate microssegundos como horas: minutos: segundos, etc

28

O seguinte é inspirado em uma pergunta que surgiu hoje no Stack Overflow .

Dado um número de microssegundos, 0 <= n <= 86400000000(por exemplo 12345678900), produza uma string formatada hh:mm:ss:000:000, por exemplo 03:25:45:678:900.

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

Eu tenho uma solução em Python em 209 bytes, mas pode ir mais baixo?

Sam
fonte
1
Agora percebo que esse não é realmente um formato padrão para os tempos de escrita e hh:mm:ss.000000provavelmente teria sido melhor (e mais fácil). Ainda assim, não posso mudar isso agora.
Sam
1
Por curiosidade, qual foi o post do SO?
Digital Trauma
@DigitalTrauma stackoverflow.com/questions/31251377 por um usuário relativamente novo. Uma resposta correta já havia sido escolhida, eu estava apenas brincando no IDLE e tive uma compreensão grotesca de um dicionário que não era uma resposta particularmente boa para a pergunta. Alguém viu e apontou este site em um comentário. Eu vim aqui, escrevi uma pergunta (um pouco diferente da postagem do SO) e também escrevi uma versão muito melhorada da minha resposta (que eu não publiquei e que agora é redundante para todas as respostas muito mais compactas e imaginativas abaixo) .
Sam
Existe um limite para o número de horas na entrada?
FUZxxl 07/07/2015
Sim, arbitrariamente eu fiz isso <= 86400000000 microsseg, então <= 24 horas.
Sam

Respostas:

15

Python 2, 82 79 bytes

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

Constrói a string, iterando através de uma série de divmods. O único pedaço chique é o %7/2, que mapeia 1000 -> 3e 60 -> 2.

Sp3000
fonte
6

Pitão, 31 bytes

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

Experimente online: Demonstração

Explicação:

                                 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
Jakube
fonte
5

Bash + coreutils, 61

O idioma "mainstream" mais curto até agora ...

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

Saída de teste:

$ 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
$ 
Trauma Digital
fonte
4

CJam, 37 35 34 bytes

Isso é muito bonito .. Golfing now ..

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

ATUALIZAÇÃO: 1 byte salvo graças ao @ Sp3000

Experimente online aqui

Optimizer
fonte
4

C, 97 bytes

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)

Código do teste:

int main(int intc, char **argv)
{
    long long n = atoll(argv[1]);
    f(n);
}
algum usuário
fonte
1
As respostas em C devem ser um programa completo; não é um trecho.
NobodyNada - Reinstate Monica
Não é mencionado na pergunta. Existe algum tipo de requisito global?
algum usuário
Lacunas que são proibidas por padrão
NobodyNada - Restabelecer Monica
Não. Se você ler a resposta, está apenas usando C como exemplo. A regra se aplicaria a todos os idiomas. Além disso, a resposta é muito disputada - veja o comentário mais bem avaliado. A questão de fundo é que a questão precisa declarar claramente se é necessário um programa completo.
algum usuário
3
Muitas respostas sobre esta utilização local de funções em vez de programas completos - por exemplo, eu não acho que eu já vi uma resposta Java que era um programa completo ...
Jerry Jeremias
4

q (34)

Tenho certeza que pode ser mais curto

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

por exemplo

q)f:":"sv 0 8 11__[;8]15$2_($)16h$1e3*
q)f 12345678900
"03:25:45:678:900"
skeevey
fonte
4
algum compilador online? em outras palavras - Como eu o executo como uma pessoa preguiçosa?
Optimizer
Versão de 32 bits está disponível gratuitamente em kx.com
skeevey
bom local. infelizmente a correção adiciona alguns caracteres
skeevey
1
você pode cortar mais bytes aqui":"sv 0 8 11__[;8]15$2_($)"n"$1e3*
WooiKent Lee
3

Julia, 110 96 95 bytes

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])

Isso cria uma função sem nome que aceita um número inteiro como entrada e retorna uma string. Para chamá-lo, dê um nome, por exemplo f=t->....

Ungolfed + explicação:

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

Exemplos:

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

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

julia> f(86400000000)
"24:00:00:000:000"
Alex A.
fonte
Agradável. Você ganha meu voto porque você inspirou minha resposta Matlab :-)
Hoki
3

C #, 179 175 bytes

Quando você tem embutidos à sua disposição, por que não usá-los?

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,":"));}

Com melhor formatação:

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

Excel, 65 63 caracteres

Supondo que seus microssegundos estão em A1 :

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

Saída:

        A              B
1            0  00:00:00:000:000
2  12345678900  03:25:46:678:900
3  86400000000  24:00:00:000:000
Mão-E-Comida
fonte
2

Perl, 141 78 bytes

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

77 bytes de código, +1 para o -nsinalizador. Correr com:

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

Agradeço a Thomas Kwa e à chilemagic por reduzirem meu código quase pela metade.

ASCIIThenANSI
fonte
Eu acho que 3600000000pode ser 36e8.
lirtosiast
Em vez de chomp($n=<STDIN>);você pode executá-lo como uma linha com a -nbandeira (que conta como 1 caractere). Você também não precisa de int(..)cada um $_. Aplicando a dica de Thomas também, podemos reduzi-la echo 12345678900 | perl -ne'printf"%02d:%02d:%02d:%03d:%03d\n",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_%1e3'e pode até haver uma maneira mais curta também!
hmatt1
Você também não precisa da \nstring de saída. Você também pode substituir a string por"%02d:"x3 ."%03d:%03d"
hmatt1
@chilemagic O uso de "eco" conta como um aumento de bytes?
ASCIIThenANSI
@ASCIIThenANSI isso não acontece porque não faz parte do seu programa. Os caracteres que você contaria são os que estão entre aspas simples, ou seja, printf"%02d:%02d:%02d:%03d:%03d\n",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_‌​%1e3e você adiciona um byte adicional ao -nsinalizador. Se você usou, -nlepor exemplo, isso contaria como 2 adicionais (para noe o l). Você obtém -oe o e(ou Ese precisar usar say) gratuitamente.
precisa saber é
1

Matlab - 88 89 bytes

Obteve um byte com uma solução sem usar a função interna:

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

Crie uma função embutida que use um argumento de entrada numérica te retorne uma string.

ele usa uma combinação vetorizada de fixe modpara separar os elementos de tempo e depois exibir.

é um pouco frustrante que a formatação da string de saída leve muito mais do que os próprios cálculos ...

Teste:

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

Versão de 89 bytes:

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

Ele divide o número, usa uma função interna para a parte hh: mm: ss, que não pode lidar com microssegundos, para que a sequência seja concluída com a combinação de fixe modoperações

Hoki
fonte
1

JavaScript (ES6), 128 118 116 111 bytes

Provavelmente existe algum potencial de golfe nisso.

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

Demo

É o ES6, portanto, apenas o Firefox, por enquanto, de qualquer maneira:

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

rink.attendant.6
fonte
A primeira verificação não é necessária, pois a pergunta é explícita: 0 <= n <= 86400000000
edc65
@ edc65 Sem a primeira verificação, só consigo obter um intervalo de 0 ≤ n <86400000000, pois 8.64e10 passaria para o dia seguinte.
precisa saber é o seguinte
Ah, certo, eu senti falta disso. toJSON () em vez de toISOString ()?
711515
1

C, 113 103 105 bytes

EDIT: empurrado mais alguns bytes

CORRECÇÃO: tipo longo removido, graças a algum usuário

Não é a resposta C mais curta, mas me diverti um pouco com retornos de carro, então senti que alguém poderia gostar disso.

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

Chame assim:

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

    return 0;
}
Andrea Biondo
fonte
Depende da plataforma, "long" pode ter apenas 32 bits. (consulte en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models ). Evitei o problema declarando "f" como macro em vez de função.
algum usuário
Eu percebi isso. Eu assumi o GCC no x64, corrigindo-o amanhã.
Andrea Biondo
0

CoffeeScript, 127 bytes

Adotou a abordagem na resposta da ASCIIThenANSI . É uma pena que a API do JavaScript Console não tenha espaços reservados de formato para números de preenchimento.

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
rink.attendant.6
fonte
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 
blabb
fonte
0

F #, 111 92 102 bytes

Primeira iteração: ideia base.

Segunda iteração: Constantes menores

Terceira iteração: Formatação correta para partes de um dígito.

Observe que essa função deve receber um int64 para funcionar.

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)

Exemplo de saídas:

f 0L           -> "00:00:00:000:000"
f 12345678900L -> "03:25:45:678:900"
f 86400000000L -> "24:00:00:000:000"
Mão-E-Comida
fonte
0

PHP - 115 102 bytes

Uma solução em 155 bytes (agrupada aqui em 3 linhas para facilitar a leitura):

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

A segunda linha calcula (de dentro para fora) os valores exatos dos componentes começando com os microssegundos.

A versão mais curta (115 bytes, agrupada em duas linhas para facilitar a leitura):

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

Ele também usa atribuições incorporadas para calcular a conversão do número de microssegundos de entrada em milissegundos, segundos, minutos e horas usando números de ponto flutuante. O operador de módulo ( %) e o formato do número decimal ( %d) de printf()são usados ​​para forçá-los a números inteiros (a parte fracionária é ignorada).

Outra solução que usa as funções de data (102 bytes)

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

A parte hours: minutes: seconds é tratada pelas funções de data do PHP gmdate()e strtotime(), os mil e microssegundos são extraídos como seqüências de caracteres do valor de entrada.

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
axiac
fonte
0

Java, 215 bytes

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

O método ffaz alguns cálculos npara calcular as horas, minutos etc. e delega ao método ppara formatar cada valor corretamente.

Formatado:

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));
}
RCB
fonte
-1

Ruby - 82 bytes

puts (t=Time.at(0,gets.to_i)).strftime("%2H:%2M:%2S:%3L:#{(t.usec%1000).to_s.rjust(3,?0)}")
Xenotoad
fonte
2
Mas contei 91 bytes. Também funciona apenas no fuso horário UTC.
precisa saber é o seguinte