【问题标题】:PowerShell dates not comparing correctlyPowerShell 日期未正确比较
【发布时间】:2019-03-06 12:58:51
【问题描述】:

我正在尝试在本月的最后一个工作日重新启动电脑。该脚本每天晚上 7:25 运行,目标是检查今天的日期,看看它是否是该月的最后一个工作日。如果是,它会重新启动 PC。如果不是,则记录它不是。

我在想也许 PowerShell 正在按滴答声进行比较,而在 Get-Weekday 函数和 Get-Date 函数的运行时间之间滴答声会稍微偏离。

日志摘录:

COMP1 - 09/26/2018 17:24:08 - Not last weekday of month 09/28/2018 17:24:08 > 09/26/2018 17:24:08 
COMP1 - 09/27/2018 17:24:09 - Not last weekday of month 09/28/2018 17:24:09 > 09/27/2018 17:24:09 
COMP1 - 09/28/2018 17:24:01 - Not last weekday of month 09/28/2018 17:24:01 > 09/28/2018 17:24:01 
COMP1 - 09/28/2018 17:24:01 - Not last weekday of month 09/28/2018 17:24:01 > 09/28/2018 17:24:01 

代码:

#Gets last weekday of the month
function Get-Weekday {
    param(
        $Month = $(Get-Date -format 'MM'),
        $Year = $(Get-Date -format 'yyyy'),
        $Days = 1..5
        )
    $MaxDays = [System.DateTime]::DaysInMonth($Year, $Month)
    1..$MaxDays | ForEach-Object {
            Get-Date -day $_ -Month $Month -Year $Year |
              Where-Object { $Days -contains $_.DayOfWeek }  
    }
}

    #Last day of the month
    $lwom = (Get-Weekday -Month (Get-Date).Month) | Select-Object -Last 1
    #Returns:  09/28/2018 17:24:16

    # Get Today's date.
    $ModDate = Get-Date
    #Returns:  09/28/2018 17:24:16

    #If Last day of month = Today's Date    
    if ( $lwom -eq $ModDate ) { 


        #Creates the wscript shell for the popup -- box automatically closes after 10 seconds, script sleeps for 60
        $wshell = New-Object -ComObject Wscript.Shell
        $wshell.Popup("This computer will reboot in 60 seconds.  Click OK and save your work!",10,"Save Your Data",48+0)
        $xCmdString = {sleep 60}
        Invoke-Command $xCmdString

        #Next popup created to reboot in 5 seconds.  
        $wshell.Popup("Rebooting...",4,"Rebooting",48+0)
        $xCmdString = {sleep 5}
        Invoke-Command $xCmdString
        Restart-Computer -Force
          }

    else { 
        Add-Content 'EOM-reboot_log.txt' "$env:computername - $ModDate - Not last weekday of month $lwom > $ModDate " 
         }

最终解决方案:

function LastDayThisMonth {
    return (Get-Date -Day 1).Date.AddMonths(1).AddDays(-1)
}

function WorkingDay {
    param ([datetime]$date=(Get-Date).Date)
    While (!([int]$date.DayOfWeek % 6)){$date=$date.AddDays(-1)}
    Return $date.Date
}

    $lwom = WorkingDay -Date (LastDayThisMonth) #Does not need .Date because it's already in the function.
    $ModDate = (Get-Date).Date  # .Date on the variables will return the date and ignores the time.  Time become 12:00:00 AM of both da


    if ( $lwom -eq $ModDate ) { 

                #Writes to the log file.
                Add-Content 'c:\EOM-reboot_log.txt' "$env:computername - $ModDate -  End of Month Weekday" 

                #Creates the wscript shell for the popup -- box automatically closes after 10 seconds, script sleeps for 60
                $wshell = New-Object -ComObject Wscript.Shell
                $wshell.Popup("This computer will reboot in 60 seconds.  Click OK and save your work!",10,"Save Your Data",48+0)
                $xCmdString = {sleep 60}
                Invoke-Command $xCmdString

                #Next popup created to reboot in 5 seconds.  
                $wshell.Popup("Rebooting...",4,"Rebooting",48+0)
                $xCmdString = {sleep 5}
                Invoke-Command $xCmdString
                Restart-Computer -Force
          }

    else { 
        Add-Content 'c:\EOM-reboot_log.txt' "$env:computername - $ModDate - Not last weekday of month $lwom > $ModDate " 
 }

【问题讨论】:

  • 您保证它们会同时运行? $lwom -eq $ModDate 正在比较日期和时间$lwom.Date -eq $ModDate.Date 可能就是您要找的。​​span>

标签: powershell


【解决方案1】:

我在想也许 PowerShell 正在按刻度进行比较,而 Get-Weekday 函数和 Get-Date 函数的运行时间之间的刻度略有不同。

是的,这很容易测试...

$date1 = Get-Date
$date2 = Get-Date

$date1.ToString("dd-MM-yyyy hh:mm:ss:fff")
$date2.ToString("dd-MM-yyyy hh:mm:ss:fff")

$date1 -eq $date2

重复运行此操作将显示成功和失败的混合,并表明datetime 相等的唯一方法是每个 日期/时间值分别相同。

01-10-2018 09:11:02:729
01-10-2018 09:11:02:730
False

01-10-2018 09:11:04:378
01-10-2018 09:11:04:378
True

话虽如此,

$lwom -eq $ModDate 正在比较日期和时间$lwom.Date -eq $ModDate.Date 只会查看日期本身。因此,除非您在午夜之前运行此程序,否则将获得一致且可预测的结果。

【讨论】:

  • 谢谢!我将 .Date 片段与 LotPings 答案结合在一起。
【解决方案2】:

通过这种方式,IMO 更容易获取当前月份的最后一天:

function LastDayThisMonth {
    return (Get-Date -Day 1).Date.AddMonths(1).AddDays(-1)
}

获取给定日期/今天的最后一个工作日的函数:

function WorkingDay {
    param ([datetime]$date=(Get-Date).Date)
    While (!([int]$date.DayOfWeek % 6)){$date=$date.AddDays(-1)}
    Return $date.Date
}
  • 这里(!([int]$date.DayOfWeek % 6)) 在周六/周日评估为真,因此减去一天

所以在 2018 年 9 月 30 日这个:

$lwom = WorkingDay -Date (LastDayThisMonth)

返回

09/28/2018 00:00:00

避免毫秒/滴答问题。

编辑为了完整起见,增强功能 WorkingDay 带有 -After 开关以获取下一个 WorkingDay(开启)或给定日期/今天之后。

function WorkingDay {
    param ([Parameter(Mandatory=$False,Position=0)] [datetime]$Date=(Get-Date).Date,
           [Parameter(Mandatory=$False,Position=1)] [switch]$After)
    If($PSBoundParameters.ContainsKey("After")){[int]$Offset=1}else{[int]$Offset=-1}
    While (!([int]$Date.DayOfWeek % 6)){$Date=$Date.AddDays($Offset)}
    Return $Date.Date
}

"Date       WDayBefore WDayAfter"
"----       ---------- ---------"
-7..7|%{
    $Date=(get-Date).Date.AddDays($_)
    "{0,-10:ddd dd} {1,-10:ddd dd} {2,-10:ddd dd} " -f `
        $Date,
        (WorkingDay -Date $Date),
        (WorkingDay -Date $Date -After )
}

测试例程的输出(德语语言环境):

> Q:\Test\2018\10\01\SO_17-56.ps1
Date       WDayBefore WDayAfter
----       ---------- ---------
Mo 24      Mo 24      Mo 24
Di 25      Di 25      Di 25
Mi 26      Mi 26      Mi 26
Do 27      Do 27      Do 27
Fr 28      Fr 28      Fr 28
Sa 29      Fr 28      Mo 01
So 30      Fr 28      Mo 01
Mo 01      Mo 01      Mo 01
Di 02      Di 02      Di 02
Mi 03      Mi 03      Mi 03
Do 04      Do 04      Do 04
Fr 05      Fr 05      Fr 05
Sa 06      Fr 05      Mo 08
So 07      Fr 05      Mo 08
Mo 08      Mo 08      Mo 08

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 2018-09-25
    • 2016-02-24
    • 2013-08-10
    相关资源
    最近更新 更多