我想将整数(毫秒)转换为以下格式:
HH:MM:SS,SSS
例如时间戳12,5秒是00:00:12,500
,1小时38分10秒就像01:38:10,000
一样。
我是Lisp编程的新手,但这是我到目前为止所做的。
(defun ms->time (ms)
(let ((hours 0)
(minutes 0)
(seconds ms))
(progn
(and (>= seconds 3600000)
(progn
(setq hours (floor (/ seconds 3600000)))
(setq seconds (mod seconds 3600000))))
(and (>= seconds 60000)
(progn
(setq minutes (floor (/ seconds 60000)))
(setq seconds (mod seconds 60000))))
(format nil "~2,'0d:~2,'0d:~6,'0:d" hours minutes seconds))))
这是简单的输出:
CL> (ms->time 12500)
"00:00:12,500"
CL> (ms->time 5890000)
"01:38:10,000"
看起来很棒,完全按照我的意愿。然而...
CL> (ms->time 0)
"00:00:000000"
CL> (ms->time 999)
"00:00:000999"
如何解决此问题? format
非常先进,我很确定有办法做我需要的事情。当然,如果你有任何想法如何改变我的功能,请更多 lispy - 请不要犹豫。我目前的方法与我的C ++版本几乎相同。
谢谢!
答案 0 :(得分:4)
一个简单的解决方案是将秒分成他们自己的组件,如小时和分钟。我还使用LET*
来隐藏MS
,以避免出现SETQ
个变量:
(defun ms->time (ms)
(let* ((hours (floor ms 3600000))
(ms (mod ms 3600000))
(minutes (floor ms 60000))
(ms (mod ms 60000))
(seconds (floor ms 1000))
(ms (mod ms 1000)))
(format nil "~2,'0d:~2,'0d:~2,'0d,~3,'0d"
hours minutes seconds ms)))
(ms->time 0)
;=> "00:00:00,000"
(ms->time 999)
;=> "00:00:00,999"
我遗漏了检查是否有足够的毫秒来制作小时或分钟。数学运算无论如何,我无法想象额外的计算是一个瓶颈。
答案 1 :(得分:4)
关于风格(请参阅jkiiski&#39的功能改进答案):
PROGN
中LET
AND
是不寻常的,避免(floor (/ x a))
是(floor x a)
您的代码可以写得更短。
&aux
。通过删除LET
。WHEN
代替AND
SETF
代替SETQ
- 它可以设置多个地方示例强>:
(defun ms->time (ms &aux (hours 0) (minutes 0) (seconds ms))
(when (>= seconds 3600000)
(setf hours (floor seconds 3600000)
seconds (mod seconds 3600000)))
(when (>= seconds 60000)
(setf minutes (floor seconds 60000)
seconds (mod seconds 60000)))
(format nil "~2,'0d:~2,'0d:~6,'0:d" hours minutes seconds))
答案 2 :(得分:3)
我可能会通过使用floor
返回两个值(除法的整数部分以及提醒)这一事实来做到这一点。
(defun ms->time (ms &optional (stream nil))
(multiple-value-bind (rest ms) (floor ms 1000)
(multiple-value-bind (rest s) (floor rest 60)
(multiple-value-bind (h m) (floor rest 60)
(format stream "~2,'0d:~2,'0d:~2,'0d,~3,'0d" h m s ms)))))