【问题标题】:Is there a way to use Powershell Stopwatch as a counter from a predetermined time?有没有办法从预定时间使用 Powershell 秒表作为计数器?
【发布时间】:2019-11-05 12:43:07
【问题描述】:

我一直在寻找一种方法来使用 powershell 创建逐秒计时器/计数器,但使用从其开始的历史日期/时间。

我发现的所有示例都使用秒表(很棒),但这似乎不适用于“预加载”日期/时间。只有当前时间。

从几个地方提取想法后,我得到了一个工作脚本,但很想知道是否有更好的方法来做到这一点?

write-host "Started at $(get-date)"

for ($t=1; $t -le 300; $t++) {
$date = Get-Date
$datediff =(NEW-TIMESPAN -Start $StartDate -End $date).ToString()
$datediff | OUT-FILE "C:\Temp\ChronoDiff.txt"
    sleep 1
}

【问题讨论】:

  • [1] Get-Date 相当慢,所以它会给你的循环增加明显的延迟。请改用[datetime]::Now。 [2] 你得到了 negative 次。 [grin] 你可能会颠倒你的日期时间数学。 [3] 不需要New-TimeSpan。只需直接将两个日期时间项目相减即可。这也将消除可检测到的延迟。 [4] 您每次都在覆盖您的输出文件。为什么?文件写入不仅会大大减慢速度,而且在事后写入该文件更有意义。
  • [5] for 循环比foreach 循环慢。对于小计数它没有区别,但您可能想要使用更有效的循环。 [6] 不需要使用$Date$DateDiff 变量。只需像这样一步完成日期时间数学... >>> ([datetime]::Now - $StartDate).ToString()
  • 感谢您的回复。回复:“你每次都在覆盖你的输出文件。为什么?”我目前正在使用一个名为 Snaz 的免费软件工具来进行计数以输出到文件(由另一个应用程序监控和显示),但是 Snaz 它有一个邪恶的时间漂移​​,这使得它在一段时间内不准确,超过几个小时。这个脚本是我试图制作一个尽可能准确的时间计数器,但我不介意每 30 秒左右跳过一秒以保持准确
  • 感谢您对项目 [4] 的“为什么”以及为什么不准确是可以接受的。 [咧嘴]

标签: powershell timer count counter


【解决方案1】:

这是一个很好的解决方案。
如果您正在寻找具有输入属性(您的特定开始日期/时间)的 StopWatch 函数,请将您的代码放入具有 StopWatch 名称的函数中。

    function StopWatch ([datetime]$StartDate) {
        do {
            write-host "$((New-TimeSpan $StartDate (get-date)).tostring())`r" -NoNewline
            sleep 1
        } while ($true)
    }

    C:\PS>StopWatch 1.1.2019
    C:\PS>StopWatch '1.1.2019 12:20'

【讨论】:

    【解决方案2】:

    这是完成工作的另一种方法。 [grin] 它做了什么...

    • 使用[datetime]::Now获取当前时间
      这明显比Get-Date 快。
    • 将代码捆绑到具有标准名称格式的函数中
    • 使用foreach 而不是for
      第一个比第二个快,因为它只进行一次测试,然后简单地迭代结果范围,而不是测试每次通过。
    • 使用直接日期时间数学而不是较慢的New-TimeSpan
    • 从当前时间减去开始时间
      您的代码为您提供了负时间间隔。我想你真的想要“多久了?”而不是“开始日期过去多长时间?”。
    • 使用Start-Sleep cmdlet 的全名
      最好使用任何 cmdlet/函数/参数的全名,以便您拥有易于扫描的代码。

    这是代码...

    function Get-TimerSeconds
        {
        [CmdletBinding()]
        Param (
            [datetime]
            $StartDate = [datetime]::Now,
    
            [int]
            $TotalSeconds = 10
            )
    
        begin {}
    
        process
            {
            foreach ($Second in 1..$TotalSeconds)
                {
                ([datetime]::Now - $StartDate).ToString()
                Start-Sleep -Seconds 1
                }
            }
    
        end {}
    
        }
    

    使用Get-TimerSeconds 截断输出...

    00:00:00
    00:00:01.0170000
    ...
    00:00:08.1150000
    00:00:09.1290000
    

    使用Get-TimerInfo -StartDate '2019-11-01 21:31:41' -TotalSeconds 15 截断输出...

    3.13:23:06.4170000
    3.13:23:07.4320000
    ...
    3.13:23:19.6000000
    3.13:23:20.6150000
    

    【讨论】:

      猜你喜欢
      • 2020-07-04
      • 1970-01-01
      • 1970-01-01
      • 2020-06-24
      • 1970-01-01
      • 2021-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多