Konversi Waktu Desimal Hari

15

pengantar

Waktu membingungkan. Enam puluh detik hingga satu menit, enam puluh menit hingga satu jam, dua puluh empat jam per hari (dan belum lagi sialnya am / pm!).

Tidak ada ruang untuk kekonyolan seperti saat ini, jadi kami telah memutuskan untuk mengadopsi satu-satunya alternatif yang masuk akal: hari desimal! Dengan kata lain, setiap hari dianggap 1 unit keseluruhan, dan apa pun yang lebih pendek ditulis sebagai pecahan desimal hari itu. Jadi, misalnya: "12:00:00" akan ditulis sebagai "0,5", dan "01:23:45" mungkin ditulis sebagai "0,058159".

Karena akan membutuhkan waktu untuk membiasakan diri dengan sistem yang baru, Anda ditugasi untuk menulis sebuah program yang dapat mengkonversi di antara mereka di kedua arah.

Tantangan

Tulis program dalam bahasa pilihan Anda, yang diberi waktu modern dalam format ISO-8601 "hh: mm: ss", akan mengembalikan unit pecahan desimal yang setara. Demikian juga, mengingat pecahan desimal, program harus mengembalikan waktu dalam format modern yang ditentukan sebelumnya.

Anda dapat membuat asumsi berikut:

  • Input dan output waktu modern dapat berkisar dari "00:00:00" hingga "24:00:00"
  • Input dan output waktu desimal dapat berkisar dari "0" hingga "1", dan harus dapat menerima / output hingga setidaknya 5 tempat desimal (seperti "0,12345"). Lebih presisi bisa diterima
  • Program harus dapat mengetahui arah konversi yang akan dijalankan berdasarkan input
  • Anda tidak dapat menggunakan fungsi / perpustakaan terkait waktu

Pemenang akan ditentukan oleh kode terpendek yang memenuhi kriteria. Mereka akan dipilih dalam setidaknya 7 unit hari desimal, atau jika / ketika ada cukup kiriman.

Contohnya

Berikut adalah (n sengaja) sepotong kode JavaScript yang ditulis dengan buruk untuk digunakan sebagai contoh:

function decimalDay(hms) {
    var x, h, m, s;
    if (typeof hms === 'string' && hms.indexOf(':') > -1) {
        x = hms.split(':');
        return (x[0] * 3600 + x[1] * 60 + x[2] * 1) / 86400;
    }
    h = Math.floor(hms * 24) % 24;
    m = Math.floor(hms * 1440) % 60;
    s = Math.floor(hms * 86400) % 60;
    return (h > 9 ? '' : '0') + h + ':' + (m > 9 ? '' : '0') + m + ':' + (s > 9 ? '' : '0') + s;
}
decimalDay('02:57:46'); // 0.12344907407407407
decimalDay('23:42:12'); // 0.9876388888888888
decimalDay(0.5); // 12:00:00
decimalDay(0.05816); // 01:23:45
Mwr247
sumber
Hmm ... 60 hampir 64. Aku ingin tahu seperti apa waktu jika ada 64 detik dalam satu menit dan 64 menit dalam satu jam (dan 16 atau 32 jam dalam sehari).
1
Apakah kita harus menangani detik kabisat? jadi 23:59:60 adalah 1 detik dari akhir hari kedua 86401?
Sparr
1
@Sparr Tidak perlu khawatir tentang detik kabisat. Ini adalah masa depan, di mana kami telah memutuskan bahwa itu konyol untuk satu detik dianggap sebagai nilai absolut sementara juga mengikatnya dengan kecepatan relatif dari rotasi bumi;)
Mwr247
1
@MichaelT Ini akan menjadi dunia impian pemrogram = P
Mwr247
1
@ Mwr247 ya. DNS TTL telah (memiliki?) Bidang yang nmana nadalah 2 ^ n detik. Jadi nilai '6' memiliki TTL sekitar 1 menit. Nilai '12' memiliki TTL sekitar 1 jam. '15' sekitar 8 jam dan seterusnya. Itu memungkinkan satu byte untuk menentukan batas waktu dan memberi Anda kontrol yang cukup untuk waktu pendek atau panjang.

Jawaban:

6

CJam, 58 56 42 byte

Saya yakin ini terlalu panjang dan bisa bermain golf banyak. Tapi ini untuk pemula:

86400q':/:d_,({60bd\/}{~*i60b{s2Ue[}%':*}?

Cobalah online di sini

Pengoptimal
sumber
Heh, kami punya ide serupa
aditsu
@aditsu Oh !. Tidak melihat milik Anda sebelum memperbarui milik saya dan kemudian terburu-buru untuk bepergian.
Pengoptimal
Anda tahu apa .. jangan ragu untuk menggunakan kode 86400q':/:d_,({60bd\/}{~*mo60bAfmd2/':*}?saya:, saya menghapus jawaban saya. The moadalah agar 0.058159 mengkonversi ke 01:23:45
aditsu
3

Python 2, 159 150 141 + 2 = 143 Bytes

Solusi mudah, mungkin bisa jauh lebih pendek. Akan mengerjakannya.

Menambahkan dua byte ke akun untuk input yang perlu dimasukkan dalam "s. Juga, Sp3000 menunjukkan masalah dengan eval () menafsirkan oktal, dan menunjukkan cara untuk mempersingkat pemformatan, menggunakan peta () dan menghapus satu cetakan.

n=input();i=float;d=864e2
if':'in n:a,b,c=map(i,n.split(':'));o=a/24+b/1440+c/d
else:n=i(n);o=(':%02d'*3%(n*24,n*1440%60,n*d%60))[1:]
print o

Lihatlah ideone di sini.

Kade
sumber
2

Javascript ( ES6 ), 116 110 byte

f=x=>x[0]?([h,m,s]=x.split(':'),+s+m*60+h*3600)/86400:[24,60,60].map(y=>('0'+~~(x*=y)%60).slice(-2)).join(':')


// for snippet demo:
i=prompt();
i=i==+i?+i:i; // convert decimal string to number type
alert(f(i))

Berkomentar:

f=x=>
    x[0] ? // if x is a string (has a defined property at '0')
        ([h, m, s] = x.split(':'), // split into hours, minutes, seconds
        +s + m*60 + h*3600) // calculate number of seconds
        / 86400 // divide by seconds in a day
    : // else
        [24, 60, 60]. // array of hours, minutes, seconds
        map(y=> // map each with function
            ('0' + // prepend with string zero
                ~~(x *= y) // multiply x by y and floor it
                % 60 // get remainder
            ).slice(-2) // get last 2 digits
        ).join(':') // join resulting array with colons
nderscore
sumber
24:00:00menghasilkan 1tetapi kebalikannya tidak benar
rink.attendant.6
@ rink.attendant.6 diperbaiki
nderscore
2

Python 3: 143 Bytes

i,k,l,m=input(),60,86400,float
if'.'in i:i=m(i)*l;m=(3*':%02d'%(i/k/k,i/k%k,i%k))[1:]
else:a,b,c=map(m,i.split(':'));m=(a*k*k+b*k+c)/l
print(m)

Byte yang sama dihitung sebagai solusi python 2 tetapi tampaknya kami mengambil pendekatan yang berbeda untuk matematika.

Serdalis
sumber
2

Julia, 152 143 142 byte

Yah, saya memperbarui pendekatan saya menjadi kurang "Julian," seperti yang mereka katakan, demi bermain golf. Untuk pendekatan yang lebih baik (meskipun kurang ringkas), lihat riwayat revisi.

x->(t=[3600,60,1];d=86400;typeof(x)<:String?dot(int(split(x,":")),t)/d:(x*=d;o="";for i=t q,x=x÷i,x%i;o*=lpad(int(q),2,0)*":"end;o[1:end-1]))

Ini menciptakan fungsi tanpa nama yang menerima string atau 64-bit floating point number dan mengembalikan 64-bit floating point number atau string, masing-masing. Untuk menyebutnya, berikan nama, mis f=x->....

Penjelasan + tidak dikumpulkan:

function f(x)
    # Construct a vector of the number of seconds in an hour,
    # minute, and second
    t = [3600, 60, 1]

    # Store the number of seconds in 24 hours
    d = 86400

    # Does the type of x inherit from the type String?
    if typeof(x) <: String
        # Compute the total number of observed seconds as the
        # dot product of the time split into a vector with the
        # number of seconds in an hour, minute, and second
        s = dot(int(split(x, ":")), t)

        # Get the proportion of the day by dividing this by
        # the number of seconds in 24 hours
        s / d
    else
        # Convert x to the number of observed seconds
        x *= d

        # Initialize an output string
        o = ""

        # Loop over the number of seconds in each time unit
        for i in t
            # Set q to be the quotient and x to be the remainder
            # from x divided by i
            q, x = divrem(x, i)

            # Append q to o, padded with zeroes as necessary
            o *= lpad(int(q), 2, 0) * ":"
        end

        # o has a trailing :, so return everything up to that
        o[1:end-1]
    end
end

Contoh:

julia> f("23:42:12")
0.9876388888888888

julia> f(0.9876388888888888)
"23:42:12"

julia> f(f("23:42:12"))
"23:42:12"
Alex A.
sumber
2

C, 137 byte

Program C penuh. Mengambil input pada stdin dan output pada stdout.

main(c){float a,b;scanf("%f:%f:%d",&a,&b,&c)<3?c=a*86400,printf("%02d:%02d:%02d",c/3600,c/60%60,c%60):printf("%f",a/24+b/1440+c/86400.);}

Tidak dikumpulkan dan berkomentar:

int main() {
    // b is float to save a . on 1440
    float a,b;
    // c is int to implicitly cast floats
    int c;

    // If the input is hh:mm:ss it gets splitted into a, b, c
    // Three arguments are filled, so ret = 3
    // If the input is a float, it gets stored in a
    // scanf stops at the first semicolon and only fills a, so ret = 1
    int ret = scanf("%f:%f:%d", &a, &b, &c);

    if(ret < 3) {
        // Got a float, convert to time
        // c = number of seconds from 00:00:00
        c = a * 86400;
        printf("%02d:%02d:%02d", c/3600, c/60 % 60, c%60);
    }
    else {
        // a = hh, b = mm, c = ss
        // In one day there are:
        // 24 hours
        // 1440 minutes
        // 86400 seconds
        printf("%f", a/24 + b/1440 + c/86400.);
    }
}
Andrea Biondo
sumber
Penggunaan scanf dan% f
sebagian pengguna
Doh! Maksud saya "pintar".
beberapa pengguna
2

J, 85 byte

Hasil:

T '12: 00: 00 '
0,5

T 0.5
12 0 0

T '12: 34: 56 '
0,524259

T 0.524259
12 34 56

T=:3 :'a=.86400 if.1=#y do.>.(24 60 60#:y*a)else.a%~+/3600 60 1*".y#~#:192 24 3 end.'

Total 85

Richard Donovan
sumber
Selamat datang di situs ini! Saya mengedit posting Anda sehingga kode tersebut akan ditampilkan sebagai kode. Adapun tautan online, yang terbaik yang saya ketahui adalah TIO . Saya akan memberi Anda tautan, tetapi saya tidak berpengalaman dengan J, jadi saya tidak tahu cara yang tepat untuk memohonnya. Juga, ini tampaknya menjadi 91 byte ketika Anda memasukkan baris pertama dan terakhir. Apakah ini benar?
DJMcMayhem
Terima kasih atas bantuan Anda! Program [a = ... untuk mengakhiri.] Adalah 77. Judulnya adalah 10. Terminator adalah 1, sehingga menghasilkan 88. Dengan tiga umpan baris yang menghasilkan 91! Saya akan mengusahakannya: o)
Richard Donovan
Sekarang turun ke 85-byte satu-liner!
Richard Donovan
1

Javascript, 194 192 190 188 byte

function(z){if(isNaN(z)){x=z.split(':');return x[0]/24+x[1]/1440+x[2]/86400}h=(z*24)|0;h%=24;m=(z*1440)|0;m%=60;s=(z*86400)|0;s%=60;return""+(h>9?'':0)+h+':'+(m>9?'':0)+m+':'+(s>9?'':0)+s}
SuperJedi224
sumber
1

JavaScript ES6, 98 130 byte

s=>s==+s?'246060'.replace(/../g,l=>':'+('0'+~~(s*=+l)%60).slice(-2)).slice(1):s.split`:`.reduce((a,b)=>+b+(+a)*60)*1/864e2;f(0.5);
Downgoat
sumber
Sayangnya, fungsi terkait waktu (seperti "Tanggal" dan "toTimeString") tidak diizinkan dalam tantangan ini. Kalau tidak, ini cara yang jauh lebih ringkas untuk melakukannya =)
Mwr247
@ Mwr247 oh tidak melihat itu, saya akan memperbaikinya kemudian
Downgoat
1

C, 156 152 byte

Saya pikir ini akan mudah untuk C. Tetapi masih cukup besar. :(

n,m=60;d(char*s){strchr(s,58)?printf("%f",(float)(atoi(s)*m*m+atoi(s+3)*m+atoi(s+6))/m/m/24):printf("%02d:%02d:%02d",(n=atof(s)*m*m*24)/m/m,n/m%m,n%m);}

Program Tes:

#include <stdio.h>
#include <stdlib.h>

int n,m=60;
d(char*s)
{
    strchr(s,':') ? 
        printf("%f",(float)(atoi(s)*m*m+atoi(s+3)*m+atoi(s+6))/m/m/24):
        printf("%02d:%02d:%02d",(n=atof(s)*m*m*24)/m/m,n/m%m,n%m);
}

int main()
{
    d("01:23:45");
    printf("\n");
    d("02:57:46");
    printf("\n");
    d("23:42:12");
    printf("\n");
    d("12:00:00");
    printf("\n");
    d("0.5");
    printf("\n");
    d("0.05816");
    printf("\n");
    d("0");
    printf("\n");
    d("1");
    printf("\n");
    return 0;
}

Keluaran:

0.058160
0.123449
0.987639
0.500000
12:00:00
01:23:45
00:00:00
24:00:00
beberapa pengguna
sumber
1

PHP, 70 69 byte

<?=strpos($t=$argv[1],58)?strtotime($t)/86400:date("H:i:s",$t*86400);

mengambil input dari argumen baris perintah, mencetak ke STDOUT:

Jika input berisi titik dua, konversikan ke waktu unix dan bagi dengan (detik per hari),
selain itu nilai numeriknya dengan (detik per hari) dan format waktu unix ke hh:mm:ss.

Titus
sumber
1

Perl, 109 108 101 + 6 ( -plaF:flag) = 107 byte

$_=$#F?($F[0]*60+$F[1]+$F[2]/60)/1440:sprintf"%02d:%02d:%02d",$h=$_*24,$m=($h-int$h)*60,($m-int$m)*60

Menggunakan:

perl -plaF: -e '$_=$#F?($F[0]*60+$F[1]+$F[2]/60)/1440:sprintf"%02d:%02d:%02d",$h=$_*24,$m=($h-int$h)*60,($m-int$m)*60' <<< 01:23:45

Cobalah di Ideone.

Denis Ibaev
sumber
0

Excel, 178 byte

=IF(LEFT(A1,2)="0.",TEXT(FLOOR(A1*24,1),"00")&":"&TEXT(MOD(FLOOR(A1*1440,1),60),"00")&":"&TEXT(MOD(FLOOR(A1*86400,1),60),"00"),((LEFT(A1,2)*60+MID(A1,4,2))*60+RIGHT(A1,2))/86400)
Wernisch
sumber