Memformat mikrodetik sebagai jam: menit: detik, dll

28

Berikut ini diilhami oleh pertanyaan yang muncul di Stack Overflow hari ini .

Diberikan sejumlah mikrodetik, 0 <= n <= 86400000000(misalnya 12345678900), menghasilkan string yang diformat hh:mm:ss:000:000, misalnya 03:25:45:678:900.

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

Saya punya solusi dalam Python dalam 209 byte, tetapi bisakah itu lebih rendah?

Sam
sumber
1
Saya menyadari sekarang bahwa ini sebenarnya bukan format standar untuk waktu menulis, dan hh:mm:ss.000000mungkin akan lebih baik (dan lebih mudah). Tetap saja, tidak bisa mengubahnya sekarang.
Sam
1
Karena penasaran, apa pos SO?
Digital Trauma
@DigitalTrauma stackoverflow.com/questions/31251377 oleh pengguna yang relatif baru. Jawaban yang benar telah dipilih, saya hanya bermain-main di IDLE dan muncul dengan pemahaman kamus yang tampak aneh yang bukan jawaban yang sangat baik untuk pertanyaan itu. Seseorang melihatnya dan menunjukkan situs ini dalam komentar. Saya datang ke sini, menulis pertanyaan (sedikit berbeda dengan posting SO), dan juga menulis versi yang lebih baik dari jawaban saya (yang belum saya posting, dan yang sekarang berlebihan untuk semua jawaban yang jauh lebih ringkas dan imajinatif di bawah) .
Sam
Apakah ada batasan jumlah jam dalam input?
FUZxxl
Ya, sewenang-wenang saya membuatnya <= 86400000000 microsec, jadi <= 24 jam.
Sam

Jawaban:

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

Membangun string, iterasi melalui serangkaian divmod. Satu-satunya bit mewah adalah %7/2, yang memetakan 1000 -> 3dan 60 -> 2.

Sp3000
sumber
6

Pyth, 31 byte

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

Cobalah online: Demonstrasi

Penjelasan:

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

Bash + coreutils, 61

Bahasa "arus utama" terpendek sejauh ini ...

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

Output tes:

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

CJam, 37 35 34 byte

Ini cukup bagus .. Golf sekarang ..

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

PEMBARUAN: 1 byte disimpan berkat @ Sp3000

Cobalah online di sini

Pengoptimal
sumber
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)

Kode Tes:

int main(int intc, char **argv)
{
    long long n = atoll(argv[1]);
    f(n);
}
beberapa pengguna
sumber
1
Jawaban dalam C seharusnya merupakan program yang lengkap; bukan cuplikan.
NobodyNada
Tidak disebutkan dalam pertanyaan. Apakah ada semacam persyaratan global?
beberapa pengguna
Celah yang dilarang secara default
NobodyNada - Reinstate Monica
Tidak. Jika Anda membaca jawabannya, itu hanya menggunakan C sebagai contoh. Aturannya akan berlaku untuk setiap bahasa. Juga, jawabannya sangat diperdebatkan - lihat komentar dengan nilai tertinggi. Intinya adalah Pertanyaan perlu menyatakannya dengan jelas jika program lengkap diperlukan.
beberapa pengguna
3
Banyak jawaban di situs ini menggunakan fungsi alih-alih program lengkap - misalnya saya tidak berpikir saya pernah melihat jawaban Java yang merupakan program lengkap ...
Jerry Jeremiah
4

q (34)

Saya yakin itu bisa lebih pendek

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

misalnya

q)f:":"sv 0 8 11__[;8]15$2_($)16h$1e3*
q)f 12345678900
"03:25:45:678:900"
skeevey
sumber
4
ada kompiler online? dengan kata lain - Bagaimana saya menjalankannya sebagai orang yang malas?
Pengoptimal
Versi 32 bit tersedia secara gratis di kx.com
skeevey
tempat yang bagus. sayangnya perbaikannya menambahkan beberapa karakter
skeevey 6-15
1
Anda dapat memotong lebih banyak byte di sini":"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])

Ini menciptakan fungsi tanpa nama yang menerima integer sebagai input dan mengembalikan string. Untuk menyebutnya, berikan nama, mis f=t->....

Penjelasan + tidak dikumpulkan:

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

Contoh:

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.
sumber
Bagus Anda mendapatkan suara saya karena Anda mengilhami jawaban Matlab saya :-)
Hoki
3

C #, 179 175 Bytes

Ketika Anda memiliki builtin yang Anda inginkan, mengapa tidak menggunakannya?

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

Dengan pemformatan yang lebih baik:

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

Unggul, 65 63 karakter

Dengan asumsi mikrodetik Anda ada di A1 :

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

Keluaran:

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

Perl, 141 78 byte

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

77 byte kode, +1 untuk -nbendera. Jalankan dengan:

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

Terima kasih kepada Thomas Kwa dan chilemagic untuk memotong ukuran kode saya hampir setengah.

ASCIIThenANSI
sumber
Saya pikir 3600000000bisa 36e8.
lirtosiast
Alih-alih chomp($n=<STDIN>);Anda dapat menjalankannya sebagai satu-liner dengan -nbendera (yang dihitung sebagai 1 karakter). Anda juga tidak perlu di int(..)sekitar masing-masing $_. Menerapkan tip Thomas juga bisa kita turunkan echo 12345678900 | perl -ne'printf"%02d:%02d:%02d:%03d:%03d\n",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_%1e3'dan mungkin ada cara yang lebih pendek juga!
hmatt1
Anda tidak perlu \ndalam string keluaran juga. Anda juga dapat mengganti string dengan"%02d:"x3 ."%03d:%03d"
hmatt1
@chilemagic Apakah menggunakan "echo" dihitung sebagai peningkatan byte?
ASCIIThenANSI
@ ASCIIThenANSI tidak karena itu bukan bagian dari program Anda. Karakter yang akan Anda hitung adalah yang berada di antara tanda kutip tunggal, yaitu printf"%02d:%02d:%02d:%03d:%03d\n",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_‌​%1e3dan kemudian Anda menambahkan byte tambahan untuk -nbendera. Jika Anda menggunakan -nlemisalnya, itu akan dihitung sebagai tambahan 2 (untuk ndan l). Anda mendapatkan -dan e(atau Ejika perlu menggunakan say) secara gratis.
hmatt1
1

Matlab - 88 89 byte

Memperoleh satu byte dengan solusi tanpa menggunakan fungsi bawaan:

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

Buat fungsi sebaris yang mengambil argumen input numerik tdan mengembalikan string.

ia menggunakan kombinasi vektor fixdan moduntuk memisahkan elemen waktu, lalu ditampilkan.

itu agak frustasi bahwa pemformatan string output mengambil begitu banyak, lebih dari perhitungan sendiri ...

Uji:

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 89 byte:

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

Membagi angka, menggunakan fungsi bawaan untuk bagian hh: mm: ss, yang tidak dapat menangani mikrodetik sehingga string dilengkapi dengan kombinasi fixdan modoperasi

Hoki
sumber
1

JavaScript (ES6), 128 118 116 111 byte

Mungkin ada beberapa potensi golf dalam hal ini.

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

Demo

ES6 jadi Firefox saja, untuk saat ini:

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
sumber
Pemeriksaan pertama tidak diperlukan, karena pertanyaannya eksplisit: 0 <= n <= 86400000000
edc65
@ edc65 Tanpa pemeriksaan pertama, saya hanya bisa mendapatkan kisaran 0 ≤ n <86400000000, karena 8.64e10 akan bergulir ke hari berikutnya.
rink.attendant.6
Oh benar, aku merindukan itu. toJSON () bukan toISOString ()?
edc65
1

C, 113 103 105 byte

EDIT: menyingkirkan beberapa byte lagi

FIX: dihapus tipe lama, terima kasih kepada beberapa pengguna

Bukan jawaban C terpendek, tapi saya bersenang-senang dengan carriage return jadi saya merasa seperti seseorang mungkin suka ini.

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

Sebut saja seperti:

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

    return 0;
}
Andrea Biondo
sumber
Tergantung pada platform, "panjang" bisa jadi hanya 32-bit. (lihat en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models ). Saya menghindari masalah dengan menyatakan "f" sebagai makro alih-alih fungsi.
beberapa pengguna
Aku tahu itu. Saya mengasumsikan GCC pada x64, memperbaikinya besok.
Andrea Biondo
0

CoffeeScript, 127 byte

Mengambil pendekatan dalam jawaban ASCIIThenANSI . Sayang sekali bahwa API Konsol JavaScript tidak memiliki penampung format untuk nomor padding.

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

Pemakaian

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 
mengoceh
sumber
0

F #, 111 92 102 byte

Iterasi pertama: Ide dasar.

Iterasi kedua: Konstanta yang lebih kecil

Iterasi ketiga: Pemformatan yang benar untuk bagian satu digit.

Perhatikan bahwa fungsi ini harus diberi int64 agar berfungsi.

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)

Output contoh:

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

PHP - 115 102 byte

Solusi dalam 155 byte (dibungkus di sini pada 3 baris untuk dibaca):

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

Baris kedua menghitung (dari dalam ke luar) nilai yang tepat dari komponen yang dimulai dengan mikrodetik.

Versi lebih pendek (115 byte, terbungkus dua baris agar mudah dibaca):

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

Ini juga menggunakan tugas yang tertanam untuk menghitung konversi jumlah input mikrodetik dalam milidetik, detik, menit dan jam menggunakan angka floating point. Operator modulus ( %) dan format angka desimal ( %d) dariprintf() kemudian digunakan untuk memaksa mereka ke angka integer (bagian fraksional diabaikan).

Solusi lain yang menggunakan fungsi tanggal (102 byte)

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

Jam: menit: bagian detik ditangani oleh fungsi tanggal PHP gmdate()danstrtotime() , mili- dan mikro-detik diekstraksi sebagai string dari nilai input.

Pemakaian:

$ 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
aksioma
sumber
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;}

Metode fmelakukan beberapa perhitungan untuk menghitung njam, menit dll. Dan mendelegasikan ke metodep untuk memformat setiap nilai dengan benar.

Diformat:

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

Pemakaian:

public void demo() {
    long n = 12345678900l;
    System.out.println(f(n));
}
RCB
sumber
-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
sumber
2
Tapi saya menghitung 91 byte. Itu juga hanya bekerja di zona waktu UTC.
jimmy23013