我有以下Python函数可以将正常时间转换为十进制时间,反之亦然:
import math
def std_to_dec(hour, minute, second):
dec_total_seconds = (3600*hour+60*minute+second)/0.864
dec_hour = int(str(dec_total_seconds/float(10000))[0])
dec_minute = int(str(dec_total_seconds/float(10000))[2:4])
dec_second = int(str(dec_total_seconds/float(10000))[4:6])
return [dec_hour, dec_minute, dec_second]
def dec_to_std(hour, minute, second):
std_total_seconds = (10000*hour+100*minute+second)*0.864
std_hour = math.floor(std_total_seconds/float(3600))
std_minute = math.floor((float(str(std_total_seconds/float(3600))[str(std_total_seconds/float(3600)).find('.'):]))*60)
std_minute_dec = (float(str(std_total_seconds/float(3600))[str(std_total_seconds/float(3600)).find('.'):]))*60
std_second = math.floor((float(str(std_minute_dec)[str(std_minute_dec).find('.'):]))*60)
return [std_hour, std_minute, std_second]
当我这样做时
print(std_to_dec(18, 21, 47))
我得到 [7, 65, 12]
,这一切都很好。但当我尝试反之亦然时,print(dec_to_std(7, 65, 12))
,我得到[18, 21, 46]
,这是不一样的。
此外,
std_to_dec(0, 0, 0)
返回错误:
dec_second = int(str(dec_total_seconds/float(10000))[4:6]) ValueError: 以 10 为基数的 int() 的文字无效:''
dec_to_std(0, 0, 0)
虽然有效。
将标准时间转换为十进制时间(反之亦然)将导致某些值出现舍入错误。
在原来的问题中,OP 正在与字符串进行转换,这是完全没有必要的。如果我们采用数学方法,问题就会变得更清楚。
def std_to_dec(hh, mm, ss):
seconds = int((((hh * 60) + mm) * 60 + ss) / 0.864)
ds = seconds % 100
seconds //= 100
dm = seconds % 100
return seconds // 100, dm, ds
def dec_to_std(hh, mm, ss):
seconds = int((((hh * 100) + mm) * 100 + ss) * 0.864)
ss = seconds % 60
seconds //= 60
sm = seconds % 60
return seconds // 60, sm, ss
standard = 18, 21, 47
print('Standard time', standard)
sd = std_to_dec(*standard)
print('Decimal time', sd)
print('Recalculated', dec_to_std(*sd))
输出:
Standard time (18, 21, 47)
Decimal time (7, 65, 12)
Recalculated (18, 21, 46)
通过使用字符串表示形式,您的代码期望有一个至少包含 6 个字符的字符串(情况并非总是如此),并忽略从第 7 个字符开始的任何字符,从而丢失精度,并导致转换回来时出现差异。
然而,一个核心问题是标准时间有 60*60*24 = 86400 种可能的次数,而小数时间有 10*100*100 = 100000(更多)可能的次数。因此,不可能存在一对一的映射,因为这样双方都需要相同数量的可能性。但是,由于标准时间的可能性较小,因此必须可以根据需要进行映射,但这意味着小数时间的某些可能性不会发生。
在将其转换为十进制时间并返回时,您可以使用以下方法始终获得相同的标准时间:
def std_to_dec(hour, minute, second):
dec = round((3600*hour+60*minute+second)/0.864)
dec_second = dec % 100
dec //= 100
dec_minute = dec % 100
dec //= 100
dec_hour = dec
return [dec_hour, dec_minute, dec_second]
def dec_to_std(hour, minute, second):
std = round((10000*hour+100*minute+second)*0.864)
std_second = std % 60
std //= 60
std_minute = std % 60
std //= 60
std_hour = std
return [std_hour, std_minute, std_second]
使用此解决方案,不可能期望相反的结果:存在小数时间,因此如果您将它们转换为标准时间并返回,它们不会产生相同的小数时间。同样,这是因为小数时间比标准时间多(当然仅使用整数时)。
例如:
std_to_dec(0, 0, 3) == [0, 0, 3]
std_to_dec(0, 0, 4) == [0, 0, 5]
这意味着小数时间 [0, 0, 4] 不会出现,也意味着如果从该小数时间开始进行逆向操作,则无法取回它:
dec_to_std(0, 0, 4) == [0, 0, 3]