PowerShell:如何检查重复的一周时间间隔?

PowerShell:如何检查重复的一周时间间隔?

我需要创建一个 PowerShell 脚本,以便每分钟收集一些数据。但是,此脚本无法在计划在同一周的同一天和同一时间发生的“技术窗口”内运行。(例如,每周二 19:00 至 23:00)此计划信息在文件中声明(例如:.\Schedule.txt):

# SCHEDULE
#
# Periods when the script will not be executed: "Prohibited Period"
# Inform: <Begin_Week_Day>:<Begin_Hour>:<Begin_Minute>:<End_Week_Day>:<End_Hour>:<End_Minute>
#
# Example: Set the Prohibited Period of script execution, every Tuesday, from 8:00 pm to 10:00 pm:
# tue:20:00:tue:22:00
#
# ATTENTION: LIMITED SCHEDULE TO THE SAME DAY OF THE WEEK!
#
qua:10:30:qua:15:40
qui:13:30:qui:23:00

在此示例中,安排了两个技术窗口。

我在第一个版本中实现了这个,只要技术窗口在同一天

$ScheduleFile=Get-Content -Path .\Schedule.txt
$NowDay=Get-Date -Format "ddd"
$NowHour=Get-Date -Format "HH"
$NowMinute=Get-Date -Format "mm"
$NowTime=[single]$NowHour+[single]$NowMinute/60
$PeriodoProibido = $false
Write-Host "========================================================================="
Write-Host "SCHEDULE ANALYSIS: Today is ${NowDay}, ${NowHour}:${NowMinute} (${NowTime})"
foreach ($line in $ScheduleFile){
    if($line.Substring(0,1) -ne "#") {
        Write-Host "-------------------------------------------------------------------------"
        $LineArray = $line.Split(':')
        <#  Schedule:  BEGIN of Prohibited Period: $LineArray[0] = Day   $LineArray[1] = Hour  $LineArray[2] = Minute
                       END   of Prohibited Period: $LineArray[3] = Day   $LineArray[4] = Hour  $LineArray[5] = Minute
        #>
        #   Convert HOUR to decimal format, include minutes.
        $LineArray[1]=[single]$LineArray[1]+[single]$LineArray[2]/60
        $LineArray[4]=[single]$LineArray[4]+[single]$LineArray[5]/60
        Write-Host "Prohibited Period: From "$LineArray[0] $LineArray[1]" to " $LineArray[3] $LineArray[4]
  
        <#  Check if NOW is DAY of Prohibited Period
        ($NowDay -eq $LineArray[0])   > Check if is DAY  do Período Proibido
        ($NowTime -gt $LineArray[1])  > Check if TIME is AFTER  the BEGIN of Prohibited Period
        ($NowTime -lt $LineArray[4])  > Check if TIME is BEFORE the BEGIN of Prohibited Period
        #>
        if($NowDay -eq $LineArray[0] -AND $NowTime -gt $LineArray[1] -AND $NowTime -lt $LineArray[4]){
            Write-Host "NOW IS A PROHIBITED PERIOD! DO NOT RUN THE SCRIPT."
            $PeriodoProibido = $true
        }
        else {
            Write-Host "The script can be executed."
        }
    }
}
Write-Host "-------------------------------------------------------------------------"
if ($PeriodoProibido) {
    Write-Host "CONCLUSION: WE ARE IN THE PROHIBITED PERIOD. DO NOT RUN SCRIPT"
}
else {
    Write-Host "CONCLUSION: You can run the script."
}
Write-Host "========================================================================="


输出类似于:

=========================================================================
SCHEDULE ANALYSIS: Today is qua, 14:42 (14.7)
-------------------------------------------------------------------------
Prohibited Period: From  qua 10.5  to  qua 15.6666666666667
NOW IS A PROHIBITED PERIOD! DO NOT RUN THE SCRIPT.
-------------------------------------------------------------------------
Prohibited Period: From  qui 13.5  to  qui 23
The script can be executed.
-------------------------------------------------------------------------
CONCLUSION: WE ARE IN THE PROHIBITED PERIOD. DO NOT RUN SCRIPT
=========================================================================

但是,如果技术窗口在一天内开始并在第二天结束,则此脚本将不起作用。我认为我是否应该使用像 Excel 或类似格式的日期格式,但我不确定。

有什么好主意可以让这个脚本变得更好吗?谢谢!

答案1

以下函数允许“技术窗口”定义为以小时为单位的时间间隔

  • 在同一工作日,例如Fri:10:30:Fri:15:40,或
  • 午夜重叠,例如Fri:22:30:Sat:05:40,或
  • 涵盖更多天数,例如Mon:22:30:Wed:05:40(一个日历周内),甚至Fri:22:30:Mon:05:40(交叉周末)。

基调(基本思想)在于使用和比较工作日数字而不是工作日名称缩写(由日期时间"ddd"自定义格式说明符)。

该脚本适用于特定的(给定的),[cultureinfo]::CurrentCulture但可以轻松本地化为.ToString方法以及AbbreviatedDayNames属性允许改变特定于文化的格式信息(通过[cultureinfo]类)......

Function TestDayTimeInterval {
    [CmdletBinding()]param(
      [Parameter(ValueFromPipeline)]
      [string]$FromTo = 'ne:00:00:ne:00:00', # ddd:HH:mm:ddd:HH:mm
      [Parameter()]
      [datetime]$Date = (Get-Date)
    )
    Write-Verbose "is $($Date.ToString("ddd HH:mm")) in $FromTo`?"
    $fAbbrDayNames = ([System.Globalization.DateTimeFormatInfo]::
            CurrentInfo.AbbreviatedDayNames).ForEach({$_.ToLower()})
        # [System.Globalization.DateTimeFormatInfo]::InvariantInfo.AbbreviatedDayNames
        # [cultureinfo]::GetCultureInfo('pt').DateTimeFormat.AbbreviatedDayNames

    $fTestDay = $fAbbrDayNames.IndexOf( $Date.ToString('ddd').ToLower())
    $fTestTime= [single]$Date.ToString("HH") +
          [math]::Round($Date.ToString("mm")/60,2)

    $aux = $FromTo -split ':'
    $fFromDay = $fAbbrDayNames.IndexOf( $aux[0].ToLower())
    $fFromTime= [single]$aux[1]+[math]::Round($aux[2]/60,2)
    $fUptoDay = $fAbbrDayNames.IndexOf( $aux[3].ToLower())
    $fUptoTime= [single]$aux[4]+[math]::Round($aux[5]/60,2)

    if ( $fFromDay -lt 0 -or $fUptoDay -lt 0 ) {
        Write-Warning "incorrect FromTo [$FromTo]"
        return $false
    }

    if ( $fFromDay -eq $fUptoDay ) {
        return  $fTestDay  -eq $fFromDay  -and
                $fTestTime -ge $fFromTime -and
                $fTestTime -le $fUptoTime
    } elseif ( $fFromDay -lt $fUptoDay ) {
        return ($fTestDay  -gt $fFromDay -and
                $fTestDay  -lt $fUpToDay)  -or
               ($fTestDay  -eq $fFromDay -and
                $fTestTime -ge $fFromTime) -or
               ($fTestDay  -eq $fUpToDay -and
                $fTestTime -le $fUpToTime)
    } else {
        return ($fTestDay  -gt $fFromDay ) -or
               ($fTestDay  -lt $fUpToDay ) -or
               ($fTestDay  -eq $fUpToDay -and
                $fTestTime -le $fUpToTime) -or
               ($fTestDay  -eq $fFromDay -and
                $fTestTime -ge $fFromTime)
    }
}

相关内容