십진 시간 변환


15

소개

시간이 혼란 스럽다. 60 초에서 1 분, 60 분에서 1 시간, 24 시간에서 하루 (그리고 성가신 am / pm은 말할 것도 없습니다!).

요즘에는 그런 어리 석음의 여지가 없으므로 우리는 유일하게 합리적인 대안을 채택하기로 결정했습니다. 즉, 매일은 전체 단위 1 개로 간주되며 더 짧은 것은 해당 날짜의 소수로 표시됩니다. 예를 들어 "12:00:00"은 "0.5"로, "01:23:45"는 "0.058159"로 작성 될 수 있습니다.

새로운 시스템에 익숙해지는 데 시간이 걸리므로, 양방향으로 변환 할 수있는 프로그램을 작성해야합니다.

도전

"hh : mm : ss"의 ISO-8601 형식으로 현대에 제공 한 경우 선택한 언어로 프로그램을 작성하면 동등한 10 진수 분수 단위가 반환됩니다. 마찬가지로 소수 부분이 주어지면 프로그램은 처음 지정된 현대 형식으로 시간을 반환해야합니다.

다음과 같은 가정을 할 수 있습니다.

  • 최신 입력 및 출력 범위는 "00:00:00"에서 "24:00:00"까지입니다.
  • 소수점 시간 입력 및 출력의 범위는 "0"에서 "1"까지 가능하며 소수점 이하 5 자리 (예 : "0.12345")까지 허용 / 출력 할 수 있어야합니다. 더 정밀한 것이 허용됩니다
  • 프로그램은 입력을 기반으로 수행 할 변환 방향을 알 수 있어야합니다.
  • 시간 관련 기능 / 라이브러리를 사용할 수 없습니다

당첨자는 기준을 달성하는 가장 짧은 코드로 결정됩니다. 그들은 적어도 7 개의 십진 일 단위로, 또는 충분한 제출이 있었을 때 / 때에 선택 될 것입니다.

여기에 의도적으로 잘못 작성된 JavaScript 코드가 예제로 사용됩니다.

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

흠 ... 60은 거의 64입니다. 1 분에 64 초, 1 시간에 64 분 (하루에 16 시간 또는 32 시간)이 있다면 어떤 시간이 될지 궁금합니다.

1
윤초를 처리해야합니까? 23:59:60은 86401 둘째 날이 끝나고 1 초입니까?
Sparr

1
@Sparr 윤초에 대해 걱정할 필요가 없습니다. 이것은 미래입니다. 1 초가 절대 값으로 간주되는 것은 어리석은 결정이며, 지구 회전의 상대 속도와도 관련이 있습니다.)
Mwr247

1
@MichaelT 그것은 프로그래머가 될 것이다 dream world = P
Mwr247

1
트윗 담아 가기 DNS TTL이 있었다 (?) 갖는다 필드 nn2 ^ N 초이다. 따라서 '6'의 값은 약 1 분의 TTL을가집니다. 값 '12'의 TTL은 약 1 시간입니다. '15'는 약 8 시간 정도였습니다. 1 바이트가 시간 종료를 정의하고 짧거나 긴 시간 동안 충분한 제어를 제공 할 수 있습니다.

답변:


6

CJam, 58 56 42 바이트

나는 이것이 너무 길고 골프를 많이 할 수 있다고 확신합니다. 그러나 여기에 초보자가 있습니다.

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

여기에서 온라인으로 사용해보십시오


Heh, 우리는 비슷한 생각을 가지고있다
aditsu

@aditsu 아!. 내 것을 업데이트하기 전에 당신을 보지 못했고 급히 출퇴근했습니다.
Optimizer

당신은 .. 내 코드를 자유롭게 사용하십시오 : 86400q':/:d_,({60bd\/}{~*mo60bAfmd2/':*}?, 나는 내 대답을 삭제하고 있습니다. 이것은 mo0.058159가 01:23:45로 변환되도록하는 것입니다
aditsu

3

파이썬 2 159 150 141 + 2 = 143 바이트

간단한 해결책은 아마도 훨씬 짧을 수 있습니다. 작동합니다.

"s로 묶어야하는 입력을 설명하기 위해 2 바이트를 추가했습니다. 또한 Sp3000은 8 진수를 해석하는 eval () 관련 문제를 지적했으며 서식을 단축하고 map ()을 사용하여 인쇄를 제거하는 방법을 보여주었습니다.

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

이곳에서 확인하십시오.


2

자바 ( ES6 ) 116 110 바이트

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

댓글 :

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

24:00:00생산 1하지만 역은 사실이 아니다
rink.attendant.6

@ rink.attendant.6 고정
nderscore

2

파이썬 3 : 143 바이트

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)

python 2 솔루션과 동일한 바이트 수이지만 수학에 대해 다른 접근 방식을 취한 것 같습니다.


2

줄리아 152 143 142 바이트

글쎄, 나는 골프를 위해서, "줄리안 (Julian)"이 아닌 접근 방식을 업데이트했다. 더 나은 (간결하지는 않지만) 접근 방식은 개정 내역을 참조하십시오.

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

문자열 또는 64 비트 부동 소수점 숫자를 허용하고 각각 64 비트 부동 소수점 숫자 또는 문자열을 리턴하는 이름없는 함수를 작성합니다. 호출하려면 이름을 지정하십시오 (예 :) f=x->....

언 골프 + 설명 :

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

예 :

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

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

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

2

C, 137 바이트

전체 C 프로그램. stdin에서 입력을 취하고 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.);}

Ungolfed 및 댓글 :

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

scanf와 % f의 명확한 사용
일부 사용자

도! 나는 "영리한"을 의미했다.
일부 사용자

2

J, 85 바이트

결과 :

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.'

총 85


사이트에 오신 것을 환영합니다! 코드가 코드로 표시되도록 게시물을 수정했습니다. 온라인 링크의 경우 내가 아는 가장 좋은 것은 TIO 입니다. 나는 당신에게 링크를 줄 것이지만, 나는 J에 경험이 없으므로 그것을 호출하는 올바른 방법을 모른다. 또한 이것은 첫 줄과 마지막 줄을 포함 할 때 91 바이트 인 것으로 보입니다. 이 올바른지?
DJMcMayhem

당신의 도움을 주셔서 감사합니다! [a = ... to end.] 프로그램은 77입니다. 제목은 10입니다. 터미네이터는 1이므로 88이됩니다. 3 개의 라인 피드로 91이됩니다! 내가 할게요 : o)
Richard Donovan

이제 85 바이트 1 라이너로 줄였습니다!
Richard Donovan

1

자바 스크립트, 194 192 190 188 바이트

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}

1

자바 스크립트 ES6, 98 130 바이트

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

불행히도이 도전에서는 시간 관련 기능 (예 : "Date"및 "toTimeString")이 허용되지 않습니다. 그렇지 않으면 훨씬 더 간결한 방법입니다 =)
Mwr247

@ Mwr247 오, 그것을 보지 못했다, 나는 이것을 고칠 것이다
Downgoat

1

C, 156152 바이트

나는 그것이 C에게는 쉬울 것이라고 생각했다. 그러나 여전히 꽤 커졌다. :(

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

테스트 프로그램 :

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

산출:

0.058160
0.123449
0.987639
0.500000
12:00:00
01:23:45
00:00:00
24:00:00

1

PHP, 70 69 바이트

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

명령 행 인수에서 입력을 받고 STDOUT으로 인쇄합니다.

입력에 콜론이 포함되어 있으면 유닉스 시간으로 변환하고 (하루 초)로 나누고,
그렇지 않으면 숫자 값을 (하루 초)로 곱하고 유닉스 시간을로 형식화하십시오 hh:mm:ss.


1

109 108 101 + 6 ( -plaF:플래그) = 107 바이트

$_=$#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

사용 :

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

Ideone에서 사용해보십시오.


0

Excel, 178 바이트

=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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.