PowerShell命令行倒计时函数Start-CountdownTimer跳秒修复咨询
PowerShell倒计时跳秒问题修复
问题原因
跳秒是两个原因共同导致的:
- 你使用了
TimeSpan的Seconds属性展示秒数,该属性仅返回时间间隔的整数秒部分,只要剩余总秒数低于对应整数值(例如剩余8.99秒时),就会直接返回8,跳过9的显示。 Start-Sleep加上控制台写入操作会产生几毫秒的额外耗时,第一次输出10秒后,等待1秒再加操作耗时,第二次采样剩余时间已经不足9秒,直接显示为8,就出现了跳秒的问题。
修复后的完整代码
Function Start-CountdownTimer{ param ( <# [int]$Days = 0, [int]$Hours = 0, [int]$Minutes = 0,#> [int]$Seconds = 0, [int]$TickLength = 1 ) $t = New-TimeSpan <#-Days $Days -Hours $Hours -Minutes $Minutes#> -Seconds $Seconds $origpos = $host.UI.RawUI.CursorPosition $spinner =@('|', '/', '-', '\\') $spinnerPos = 0 $d = (Get-Date) + $t $remain = ($d - (Get-Date)) while ($remain.TotalSeconds -gt 0){ # 向上取整总秒数,避免跳数 $displaySeconds = [Math]::Ceiling($remain.TotalSeconds) Write-Host (" {0} " -f $spinner[$spinnerPos%4]) -ForegroundColor White -NoNewline Write-Host (" Starting in {0:d1}s ..." -f $displaySeconds) $host.UI.RawUI.CursorPosition = $origpos $spinnerPos += 1 # 校准休眠时间,抵消操作耗时 $sleepTime = $TickLength - (Get-Date).Millisecond/1000 if ($sleepTime -gt 0) { Start-Sleep -Seconds $sleepTime } $remain = ($d - (Get-Date)) } $host.UI.RawUI.CursorPosition = $origpos }
核心修改点
- 新增
$displaySeconds变量,使用[Math]::Ceiling()对剩余总秒数向上取整,只要剩余时间还没到整秒阈值就不会跳数,比如剩余8.1秒时仍然显示9秒。 - 校准休眠时间,用
TickLength减去当前时间的毫秒占比,抵消前面写入操作的耗时,避免误差累计。 - 删除了冗余的
$remain = $t赋值逻辑,避免不必要的变量覆盖。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

