Umrechnung der Dezimalzeit

15

Einführung

Die Zeit ist verwirrend. Sechzig Sekunden zu einer Minute, sechzig Minuten zu einer Stunde, vierundzwanzig Stunden zu einem Tag (und ganz zu schweigen von diesem lästigen Morgen / Morgen!).

Für eine solche Dummheit ist heutzutage kein Platz mehr, deshalb haben wir uns für die einzig sinnvolle Alternative entschieden: Dezimaltage! Das heißt, jeder Tag wird als eine ganze Einheit betrachtet, und alles Kürzere wird als Dezimalbruch dieses Tages geschrieben. So würde beispielsweise "12:00:00" als "0,5" und "01:23:45" als "0,058159" geschrieben.

Da es einige Zeit dauert, um sich an das neue System zu gewöhnen, müssen Sie ein Programm schreiben, das zwischen beiden Richtungen konvertiert.

Herausforderung

Schreiben Sie ein Programm in der Sprache Ihrer Wahl, das bei einer modernen Zeit im ISO-8601-Format "hh: mm: ss" die entsprechende Dezimalbrucheinheit zurückgibt. Ebenso sollte das Programm bei einem Dezimalbruch die Zeit in dem ursprünglich angegebenen modernen Format zurückgeben.

Sie können folgende Annahmen treffen:

  • Die Ein- und Ausgabe der modernen Zeit kann von "00:00:00" bis "24:00:00" reichen.
  • Die Eingabe und Ausgabe der Dezimalzeit kann von "0" bis "1" reichen und sollte in der Lage sein, bis zu mindestens 5 Dezimalstellen (z. B. "0.12345") zu akzeptieren / auszugeben. Mehr Präzision ist akzeptabel
  • Das Programm sollte anhand der Eingabe wissen, welche Konvertierungsrichtung auszuführen ist
  • Sie können keine zeitbezogenen Funktionen / Bibliotheken verwenden

Der Gewinner wird anhand des kürzesten Codes ermittelt, der die Kriterien erfüllt. Sie werden in Einheiten von mindestens 7 Dezimaltagen ausgewählt, oder wenn / wenn es genügend Einreichungen gegeben hat.

Beispiele

Hier ist ein (absichtlich) schlecht geschriebener Teil des JavaScript-Codes, der als Beispiel dienen soll:

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
quelle
Hmm ... 60 ist fast 64. Ich frage mich, wie viel Zeit wäre, wenn es 64 Sekunden pro Minute und 64 Minuten pro Stunde (und 16 oder 32 Stunden pro Tag) gäbe.
1
Müssen wir Schaltsekunden bewältigen? Also ist 23:59:60 1 Sekunde nach dem Ende eines 86401 zweiten Tages?
Sparr
1
@Sparr Keine Angst vor Schaltsekunden. Dies ist die Zukunft, in der wir entschieden haben, dass es für eine Sekunde albern ist, als absoluter Wert betrachtet zu werden, während es gleichzeitig an die relative Geschwindigkeit der Erdrotation
gebunden ist
1
@ MichaelT Es wäre ein Programmierer Traumwelt = P
Mwr247
1
@ Mwr247 yep. DNS TTL hat (hatte?) Ein Feld, in ndem n2 ^ n Sekunden liegen. Ein Wert von '6' hatte also eine TTL von ungefähr 1 Minute. Ein Wert von '12' hatte eine TTL von ungefähr 1 Stunde. 15 war ungefähr 8 Stunden und so weiter. Es erlaubte einem Byte, das Zeitlimit zu definieren und Ihnen genügend Kontrolle für kurze oder lange Zeiten zu geben.

Antworten:

6

CJam, 58 56 42 Bytes

Ich bin sicher, das ist zu lang und kann viel golfen. Aber hier geht für den Anfang:

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

Probieren Sie es hier online aus

Optimierer
quelle
Heh, wir haben ähnliche Ideen
Aditsu
@Aditsu Oh !. Ich habe deins nicht gesehen, bevor ich meins aktualisiert habe, und hatte es dann eilig, zur Arbeit zu kommen.
Optimierer
Weißt du was? Fühle dich frei, meinen Code zu verwenden 86400q':/:d_,({60bd\/}{~*mo60bAfmd2/':*}?. Ich lösche meine Antwort. Das moist so, dass 0.058159 zu 01:23:45 konvertiert
aditsu
3

Python 2, 159 150 141 + 2 = 143 Bytes

Einfache Lösung, kann wahrscheinlich viel kürzer sein. Wird daran arbeiten.

Es wurden zwei Bytes hinzugefügt, um zu berücksichtigen, dass Eingaben in "s" eingeschlossen werden müssen. Außerdem wies Sp3000 auf ein Problem bei der Interpretation von Oktalen durch eval () hin und zeigte eine Möglichkeit, die Formatierung zu verkürzen, map () zu verwenden und einen Ausdruck zu entfernen.

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

Schau es dir auf ideone hier an.

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

Kommentiert:

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
quelle
24:00:00produziert 1aber das
Gegenteil
@ rink.attendant.6 behoben
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)

Gleiche Byteanzahl wie bei der Python 2-Lösung, aber anscheinend haben wir unterschiedliche Ansätze für die Mathematik gewählt.

Serdalis
quelle
2

Julia, 152 143 142 Bytes

Nun, ich habe meine Herangehensweise aktualisiert, um weniger "Julian" zu sein, wie man sagt, um Golf zu spielen. Eine bessere (wenn auch weniger präzise) Vorgehensweise finden Sie im Revisionsverlauf.

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

Dadurch wird eine unbenannte Funktion erstellt, die eine Zeichenfolge oder eine 64-Bit-Gleitkommazahl akzeptiert und eine 64-Bit-Gleitkommazahl bzw. eine Zeichenfolge zurückgibt. Um es zu nennen, geben Sie ihm einen Namen, z f=x->....

Ungolfed + Erklärung:

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

Beispiele:

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.
quelle
2

C 137 Bytes

Volles C-Programm. Übernimmt die Eingabe für stdin und die Ausgabe für 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 und kommentiert:

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
quelle
Sehr klare Verwendung von scanf und% f
einige Benutzer
D'oh! Ich meinte "schlau".
Einige Benutzer
2

J, 85 Bytes

Ergebnisse:

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

Insgesamt 85

Richard Donovan
quelle
Willkommen auf der Seite! Ich habe Ihren Beitrag so bearbeitet, dass der Code als Code angezeigt wird. Was einen Online-Link betrifft, ist der beste, den ich kenne, TIO . Ich würde Ihnen einen Link geben, aber ich habe keine Erfahrung mit J, daher weiß ich nicht, wie ich ihn richtig aufrufen kann. Außerdem scheint dies 91 Bytes zu sein, wenn Sie die erste und die letzte Zeile einfügen. Ist das richtig?
DJMcMayhem
Danke für Ihre Hilfe! Das Programm [a = ... bis zum Ende.] Ist 77. Der Titel ist 10. Der Terminator ist 1, das ergibt 88. Mit drei Zeilenvorschüben ergibt das 91! Ich werde daran arbeiten: o)
Richard Donovan
Nun zu einem 85-Byte-Einzeiler!
Richard Donovan
1

Javascript, 194 192 190 188 Bytes

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

JavaScript ES6, 98 130 Bytes

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
quelle
Leider sind zeitbezogene Funktionen (wie "Date" und "toTimeString") in dieser Herausforderung nicht zulässig. Ansonsten ist es eine viel
präzisere Methode
@ Mwr247 oh habe das nicht gesehen, ich werde das dann beheben
Downgoat
1

C, 156 152 Bytes

Ich dachte, es wird einfach für C, aber es ist trotzdem ziemlich groß geworden. :(

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

Testprogramm:

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

Ausgabe:

0.058160
0.123449
0.987639
0.500000
12:00:00
01:23:45
00:00:00
24:00:00
ein Benutzer
quelle
1

PHP, 70 69 Bytes

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

Nimmt Eingaben vom Kommandozeilenargument und druckt diese an STDOUT:

Wenn die Eingabe einen Doppelpunkt enthält, konvertieren Sie sie in Unix-Zeit und dividieren Sie sie durch (Sekunden pro Tag).
Anderenfalls multiplizieren Sie den numerischen Wert mit (Sekunden pro Tag) und formatieren Sie die Unix-Zeit in hh:mm:ss.

Titus
quelle
1

Perl, 109 108 101 + 6 ( -plaF:Flag) = 107 Bytes

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

Verwenden von:

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

Probieren Sie es auf Ideone.

Denis Ibaev
quelle
0

Excel, 178 Bytes

=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
quelle