Formatee microsegundos como horas: minutos: segundos, etc.

28

Lo siguiente está inspirado en una pregunta que surgió hoy en Stack Overflow .

Dado un número de microsegundos, 0 <= n <= 86400000000(ej. 12345678900), Genera una cadena formateada hh:mm:ss:000:000, ej 03:25:45:678:900.

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

Tengo una solución en Python en 209 bytes, pero ¿puede bajar?

Sam
fuente
1
Ahora me doy cuenta de que este no es realmente un formato estándar para los tiempos de escritura, y hh:mm:ss.000000probablemente habría sido mejor (y más fácil). Aún así, no puedo ir a cambiarlo ahora.
Sam
1
Por curiosidad, ¿cuál fue la publicación SO?
Trauma digital
@DigitalTrauma stackoverflow.com/questions/31251377 por un usuario relativamente nuevo. Ya se había elegido una respuesta correcta, solo estaba jugando en IDLE y se me ocurrió una comprensión de diccionario de aspecto grotesco que no era una respuesta particularmente buena a la pregunta. Alguien lo vio y señaló este sitio en un comentario. Vine aquí, escribí una pregunta (ligeramente diferente a la publicación SO), y también escribí una versión mucho mejor de mi respuesta (que no he publicado, y que ahora es redundante para todas las respuestas mucho más compactas e imaginativas a continuación) .
Sam
¿Hay un límite en el número de horas en la entrada?
FUZxxl
Sí, arbitrariamente lo hice <= 86400000000 microsec, entonces <= 24 horas.
Sam

Respuestas:

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

Construye la cadena, iterando a través de una serie de divmods. Lo único elegante es el %7/2, que asigna 1000 -> 3y 60 -> 2.

Sp3000
fuente
6

Pyth, 31 bytes

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

Pruébelo en línea: demostración

Explicación:

                                 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
fuente
5

Bash + coreutils, 61

El lenguaje "convencional" más corto hasta ahora ...

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

Prueba de salida:

$ 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
fuente
4

CJam, 37 35 34 bytes

Esto es bastante largo ... Jugar al golf ahora ...

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

ACTUALIZACIÓN: 1 byte guardado gracias a @ Sp3000

Pruébalo en línea aquí

Optimizador
fuente
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 de prueba:

int main(int intc, char **argv)
{
    long long n = atoll(argv[1]);
    f(n);
}
algun usuario
fuente
1
Se supone que las respuestas en C son un programa completo; No es un fragmento.
NobodyNada - Restablece a Monica el
No se menciona en la pregunta. ¿Hay algún tipo de requisitos globales?
algún usuario
Lagunas que están prohibidas por defecto
NobodyNada - Restablecer Mónica
No. Si lees la respuesta, solo está usando C como ejemplo. La regla se habría aplicado a todos los idiomas. Además, la respuesta es muy discutida: vea el comentario mejor calificado. La conclusión es que la pregunta debe indicarlo claramente si se requiere un programa completo.
algún usuario
3
Muchas respuestas en este sitio utilizan funciones en lugar de programas completos, por ejemplo, no creo haber visto una respuesta de Java que fuera un programa completo ...
Jerry Jeremiah
4

q (34)

Estoy seguro de que puede ser más corto

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

p.ej

q)f:":"sv 0 8 11__[;8]15$2_($)16h$1e3*
q)f 12345678900
"03:25:45:678:900"
skeevey
fuente
44
¿algún compilador en línea? en otras palabras: ¿cómo lo ejecuto como una persona perezosa?
Optimizador
La versión de 32 bits está disponible de forma gratuita en kx.com
skeevey
buen lugar. por desgracia, la corrección agrega algunos caracteres
skeevey
1
puedes cortar más bytes aquí":"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])

Esto crea una función sin nombre que acepta un entero como entrada y devuelve una cadena. Para llamarlo, dale un nombre, por ejemplo f=t->....

Ungolfed + explicación:

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

Ejemplos:

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.
fuente
Buena esa. Recibiste mi voto porque inspiraste mi respuesta de Matlab :-)
Hoki
3

C #, 179 175 bytes

Cuando tenga builtins a su disposición, ¿por qué no usarlos?

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 mejor formato:

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
fuente
3

Excel, 65 63 caracteres

Asumiendo que sus microsegundos están en A1 :

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

Salida:

        A              B
1            0  00:00:00:000:000
2  12345678900  03:25:46:678:900
3  86400000000  24:00:00:000:000
Hand-E-Food
fuente
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 la -nbandera. Corre con:

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

Gracias a Thomas Kwa y chilemagic por cortar el tamaño de mi código casi a la mitad.

ASCIIThenANSI
fuente
Creo que 3600000000puede ser 36e8.
lirtosiast
En lugar de chomp($n=<STDIN>);hacerlo, puede ejecutarlo como una línea con la -nbandera (que cuenta como 1 carácter). Tampoco necesitas el int(..)alrededor de cada uno $_. ¡Aplicando la punta de Thomas también podemos obtenerla echo 12345678900 | perl -ne'printf"%02d:%02d:%02d:%03d:%03d\n",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_%1e3'e incluso podría haber una forma más corta también!
hmatt1
Tampoco necesita el \nen la cadena de salida. También puede reemplazar la cadena con"%02d:"x3 ."%03d:%03d"
hmatt1
@chilemagic ¿El uso de "echo" cuenta como un aumento de bytes?
ASCIIThenANSI
@ASCIIThenANSI no lo hace porque no es parte de su programa. Los caracteres que contaría son los que se encuentran entre las comillas simples, es decir, printf"%02d:%02d:%02d:%03d:%03d\n",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_‌​%1e3y luego agrega un byte adicional para la -nbandera. Si usó, -nlepor ejemplo, eso contaría como un 2 adicional (para el ny el l). Obtiene el -y el e(o Esi necesita usar say) de forma gratuita.
hmatt1
1

Matlab - 88 89 bytes

Ganó un byte con una solución sin usar la función integrada:

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

Cree una función en línea que tome un argumento de entrada numérico ty devuelva una cadena.

utiliza una combinación vectorizada de fixy modpara separar los elementos de tiempo, luego se muestra.

Es un poco frustrante que el formato de la cadena de salida tome tanto, más que los cálculos en sí ...

Prueba:

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

Versión de 89 bytes:

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

Divide el número, usa una función incorporada para la parte hh: mm: ss, que no puede tratar con microsegundos, por lo que la cadena se completa con la combinación de fixy modoperaciones

Hoki
fuente
1

JavaScript (ES6), 128 118 116 111 bytes

Probablemente haya algo de golf en esto.

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

Manifestación

Es ES6, así que solo Firefox, por ahora de todos modos:

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
fuente
La primera verificación no es necesaria, ya que la pregunta es explícita: 0 <= n <= 86400000000
edc65
@ edc65 Sin la primera verificación, solo puedo obtener un rango de 0 ≤ n <86400000000, ya que 8.64e10 pasaría al día siguiente.
rink.attendant.6
Oh cierto, me perdí eso. toJSON () en lugar de toISOString ()?
edc65
1

C, 113 103 105 bytes

EDITAR: empujó algunos bytes más

REVISIÓN: tipo largo eliminado, gracias a algún usuario

No es la respuesta C más corta, pero me divertí con los retornos de carro, así que sentí que a alguien le podría gustar esto.

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

Llámalo como:

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

    return 0;
}
Andrea Biondo
fuente
Depende de la plataforma, "largo" podría ser de solo 32 bits. (ver en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models ). Evité el problema declarando "f" como macro en lugar de función.
algún usuario
Me di cuenta que. Asumí GCC en x64, lo arreglaré mañana
Andrea Biondo
0

CoffeeScript, 127 bytes

Tomó el enfoque en la respuesta de ASCIIThenANSI . Es una pena que la API de la consola de JavaScript no tenga marcadores de posición de formato para los números de relleno.

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
fuente
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
fuente
0

F #, 111 92102 bytes

Primera iteración: idea base.

Segunda iteración: constantes más pequeñas

Tercera iteración: formato correcto para porciones de un solo dígito.

Tenga en cuenta que esta función debe tener un int64 para que funcione.

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)

Salidas de ejemplo:

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

PHP - 115102 bytes

Una solución en 155 bytes (envuelta aquí en 3 líneas para facilitar la lectura):

$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 segunda línea calcula (de adentro hacia afuera) los valores exactos de los componentes que comienzan con los microsegundos.

La versión más corta (115 bytes, envuelta en dos líneas para facilitar la lectura):

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

También utiliza asignaciones incrustadas para calcular la conversión del número de entrada de microsegundos en milisegundos, segundos, minutos y horas utilizando números de coma flotante. El operador de módulo ( %) y el formato de número decimal ( %d) de printf()se utilizan para forzarlos a números enteros (se ignora la parte fraccionaria).

Otra solución que usa las funciones de fecha (102 bytes)

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

La parte horas: minutos: segundos es manejada por las funciones de fecha PHP gmdate()y strtotime(), los milisegundos y microsegundos se extraen como cadenas del 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
fuente
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;}

Method frealiza algunos cálculos npara calcular las horas, minutos, etc. y delega al método ppara formatear cada valor correctamente.

Formateado:

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
fuente
-1

Rubí: 82 bytes

puts (t=Time.at(0,gets.to_i)).strftime("%2H:%2M:%2S:%3L:#{(t.usec%1000).to_s.rjust(3,?0)}")
Xenotoad
fuente
2
Pero conté 91 bytes. También solo funciona en la zona horaria UTC.
jimmy23013