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 или что-то подобное, но я не уверен.

Есть ли какие-нибудь хорошие идеи, чтобы улучшить этот сценарий? Спасибо!

0
задан 11 November 2020 в 21:22
1 ответ

Следующая функция разрешает "технические окна", определяемые как интервал времени в часах

  • в тот же рабочий день, например Пт:10:30:Пт:15:40 или
  • перекрытие полуночи, например Пт:22:30:Сб:05:40 или
  • больше дней, например Пн:22:30:Ср:05:40 (внутри календарной недели) или даже Пт:22:30:Пн:05:40 (переходные выходные).

Основная идея (основная идея) заключается в использовании и сравнении числа дней недели вместо сокращений названий дней недели (определяемых datetime "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)
    }
}
0
ответ дан 12 November 2020 в 21:16

Теги

Похожие вопросы