任意进制转化实现秒数转时间
需求
经过会碰到这样的情况:已知经过的秒数,要如何转换成类似“XX年XX月XX天XX小时XX分钟XX秒”来进行表达。
很明显,这里需要一个转换的方法,就是进制的转换,那就来研究一下进制的转换。
内置的进制转换
在python里已经有内置的进制转换方法,直接调用就可以了,比如:
*** 十进制转成二进制:bin()
***
>>> bin(122)
'0b1111010'
** 十进制转成八进制:oct()
**
>>> oct(23)
'0o27'
** 十进制转成十六进制:hex()
**
>>> hex(123)
'0x7b'
自定义任意进制的转换
时间转换的进制是:60秒=1分钟,60分钟=1小时,可以看作是60进制的转换,系统内置的进制转换方法满足不了。
那就自己写一个任意进制的转换方法吧,通用的进制转换用的方法是 “除基取余数法”,可以参考百度:进制转换(百度百科)
进制转换示意图:
根据这个思路写出第一个版本的转换方法:
# 任意进制转化
def trans(value, base=2):
r = 0
# 定义数组用于保存结果
ret = []
while 1:
# 计算余数
r = value % base
# 计算商
value = value // base
# 把余数保存到数组
ret.append(r)
# 如果余数比基小,保存余数后退出
if value<base:
ret.append(value)
break;
# 最后要逆序一下
return ret[::-1]
测试一下运行结果:
>>> print(trans(8,2))
[1, 0, 0, 0]
>>> print(trans(19,2))
[1, 0, 0, 1, 1]
如果转换的进制大于10,那单个位上的数字0-9就不够用了,比如16进制需要用’A’-'F’来表示10到15。
接下来优化一下方法,同时加上单个位上的字符转换:
# 任意进制转化
def trans(value, base=2, chars=''):
r = 0
ret = []
while value>=base:
r = value % base
value = value // base
ret.append(r)
ret.append(value)
# 逆序
ret = ret[::-1]
# 转换字符
if chars:
charlist = list(chars)
if len(charlist) == base:
ret = list(map(lambda x:charlist[x], ret))
return ret
优化后可以减少一次循环,同时可以根据字符进行转换:
>>> print(trans(6702, 16,))
[1, 10, 2, 14]
>>> print(trans(6702, 16, '0123456789abcdef'))
['1', 'a', '2', 'e']
秒数转时间长度
上面分析的情况是数字转成任意进制的情况,每次运算的时候转换的“基数”是一样的。
但是在时间转换的时候,“基数”是变化的,比如“1小时等于60秒,1天等于24小时”,
“1个月等于30天”,“1年=12个月”,这就需要在计算的过程中变换“基数”,可以使用一个列表变量来传递“基数”的序列
# 带进位值的进制转化
def trans_any(value, base=2):
if type(base) == list:
pl = base[::-1]
i = 0
pv = pl[i]
else:
pl = []
pv = base
r = 0
ret = []
while value >= pv:
# 以下这句可以用于查看运算过程
print(value, r, pv)
r = value % pv
value = value // pv
ret.append(r)
if pl:
i += 1
if i<=len(pl):
pv = pl[i]
ret.append(value)
return ret[::-1]
来测试一下这个方法 :
>>> print(trans_any(126430,60))
126430 0 60
2107 10 60
[35, 7, 10]
>>> print(trans_any(3120419000, [10,100,12,30,24,60,60]))
3120419000 0 60
52006983 20 60
866783 3 24
36115 23 30
1203 25 12
100 3 100
[1, 0, 3, 25, 23, 3, 20]
最后给每个位加上单位,就得到最终的时间转换方法
秒数转时间长度的方法:
# 秒数转时间
def second2time(seconds):
print('%d秒 等于:'%seconds)
unit = '世纪,年,个月,天,小时,分钟,秒'.split(',')
value = trans_any(seconds, [10,100,12,30,24,60,60])
ret = list(zip(value[::-1], unit[::-1]))[::-1]
text = ''.join(map(lambda x:''.join(map(str, x)), ret))
print(ret)
print(text)
return text
测试结果:
>>> second2time(19000)
19000秒 等于:
[(5, '小时'), (16, '分钟'), (40, '秒')]
'5小时16分钟40秒'
>>> second2time(86430)
86430秒 等于:
[(1, '天'), (0, '小时'), (0, '分钟'), (30, '秒')]
'1天0小时0分钟30秒'
>>> second2time(3120419000)
3120419000秒 等于:
[(1, '世纪'), (0, '年'), (3, '个月'), (25, '天'), (23, '小时'), (3, '分钟'), (20, '秒')]
'1世纪0年3个月25天23小时3分钟20秒'
完整代码及运行截图
完整代码及运行截图如下:
#!/usr/bin/env python3
#coding:utf-8
__author__ = 'xmxoxo<xmxoxo@qq.com>'
# 任意进制转化
def trans1(value, base=2):
r = 0
# 定义数组用于保存结果
ret = []
while 1:
# 计算余数
r = value % base
# 计算商
value = value // base
# 把余数保存到数组
ret.append(r)
# 如果余数比基小,保存余数后退出
if value<base:
ret.append(value)
break;
# 最后要逆序一下
return ret[::-1]
# 任意进制转化
def trans(value, base=2, chars=''):
r = 0
ret = []
while value>=base:
r = value % base
value = value // base
ret.append(r)
ret.append(value)
# 逆序
ret = ret[::-1]
# 转换字符
if chars:
charlist = list(chars)
if len(charlist) == base:
ret = list(map(lambda x:charlist[x], ret))
return ret
print('8转2进制:')
print(trans1(8,2))
print('-'*40)
print('124 转 2 进制(trans1方法):')
print(trans1(124,2))
print('-'*40)
print('6702 转 16 进制:')
print(trans(6702, 16,))
print(trans(6702, 16, '0123456789abcdef'))
print('-'*40)
print('19000 转60进制:')
print(trans(19000,60))
# 带进位值的进制转化
def trans_any(value, base=2):
if type(base) == list:
pl = base[::-1]
i = 0
pv = pl[i]
else:
pl = []
pv = base
r = 0
ret = []
while value >= pv:
# 以下这句可以用于查看运算过程
print(value, r, pv)
r = value % pv
value = value // pv
ret.append(r)
if pl:
i += 1
if i<=len(pl):
pv = pl[i]
ret.append(value)
return ret[::-1]
print('-'*40)
print('126430转60进制 (trans_any方法):')
print(trans_any(126430,60))
print('-'*40)
print('3120419000转 时间(trans_any方法):')
print(trans_any(3120419000, [10,100,12,30,24,60,60]))
# 秒数转时间
def second2time(seconds):
print('%d秒 等于:'%seconds)
unit = '世纪,年,个月,天,小时,分钟,秒'.split(',')
value = trans_any(seconds, [10,100,12,30,24,60,60])
ret = list(zip(value[::-1], unit[::-1]))[::-1]
text = ''.join(map(lambda x:''.join(map(str, x)), ret))
print(ret)
print(text)
return text
print('-'*40)
print('秒数转时间:')
second2time(19000)
second2time(86430)
second2time(3120419000)
if __name__ == '__main__':
pass
运行截图:
[外链图片转存中…(img-JJ5uQIrP-1626853160883)]