小数时间转换


15

介绍

时间令人困惑。六十秒到一分钟,六十分钟到一小时,一天二十四小时(更不用说讨厌的上午/下午!)。

如今,没有这么大的愚蠢空间,因此我们决定采用唯一明智的选择:十进制天!也就是说,每天被认为是1个完整的单位,较短的部分则记作该天的小数部分。因此,例如:“ 12:00:00”将被写为“ 0.5”,而“ 01:23:45”将被写为“ 0.058159”。

因为要适应新系统将花费一些时间,所以您需要编写一个可以在两个方向之间进行转换的程序。

挑战

使用您选择的语言编写一个程序,该程序在ISO-8601格式为“ hh:mm:ss”的现代环境下将返回等效的十进制小数单位。同样,给定小数部分,程序应以最初指定的现代格式返回时间。

您可以进行以下假设:

  • 现代时间输入和输出的范围可以从“ 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。我想知道如果一分钟有64秒,一小时有64分钟(一天有16或32个小时)会是什么样的时间?

1
我们必须处理leap秒吗?所以23:59:60是86401第二天结束后的1秒?
Sparr

1
@Sparr无需担心leap秒。这就是未来,我们认为将一秒钟的绝对值视为绝对值,同时
又将

1
@MichaelT这将是一个程序员的梦想世界= P
Mwr247

1
@ Mwr247是的。DNS TTL已(过的?)一个字段,该字段是n其中n是2 ^ n秒。因此,值“ 6”具有大约1分钟的TTL。值“ 12”具有大约1小时的TTL。“ 15”大约是8个小时,依此类推。它允许一个字节定义超时,并为您提供足够的控制时间(短时间或长时间)。

Answers:


6

CJam,58 56 42字节

我相信这太长了,可以打很多球。但是这里适合初学者:

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

在这里在线尝试


嘿,我们有类似的想法
aidtsu退出是因为SE为EVIL,2015年

@aditsu哦!在更新我的信息之前没有看到您的信息,然后急于上下班。
Optimizer

您知道吗..随时使用我的代码:86400q':/:d_,({60bd\/}{~*mo60bAfmd2/':*}?,我正在删除答案。该mo是让0.058159皈依1时23分45秒
aditsu退出,因为SE是邪恶的

3

Python 2中,159 150 141 + 2 = 143个字节

简单的解决方案,可能要短得多。会努力的。

添加了两个字节以解决需要用“ s”括起来的输入的问题。此外,Sp3000指出了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

在此处检查ideone。


2

使用Javascript(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 2015年

@ rink.attendant.6已修复
nderscore 2015年

2

Python 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字节

好吧,为了打高尔夫球,我更新了我的方法,使之不再像他们所说的“朱利安”。有关更好(尽管不太简洁)的方法,请参阅修订历史记录。

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

取消评论并评论:

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个字节

结果:

Ť'12:00:00'
0.5

T 0.5
12 0 0

T '12:34:
56'0.524259

电话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 = ...结尾。]是77。标题是10。终结符是1,所以等于88。使用三行换行符可以得出91!我会处理:o)
Richard Donovan

现在下降到一个85字节的单线!
理查德·多诺万

1

JavaScript中,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

的JavaScript 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 2015年

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:

如果输入包含冒号,请转换为Unix时间并除以(每天的秒数),
否则将数字值除以(每天的秒数),然后将Unix时间格式化为hh:mm:ss


1

Perl中,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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.