PowerShell函数输出异常:如何仅获取工作日天数而非额外日期?
问题:PowerShell函数返回多余日期值,仅需工作日数量
我编写了PowerShell函数Get-WorkingDay,接收起始日期(startDate)和需添加的天数(Duration)参数,用于计算其中的工作日数量。计算逻辑整体正常,但输出存在问题:我需要仅返回工作日数量,却同时得到了最后检查的日期和工作日数。
当起始日期为2014.01.21时,输出结果为2014.01.31 00:00:00 7,但我只需要数字7。
函数代码如下:
Function Get-WorkingDay{ param( [Parameter(Mandatory=$True,Position=1)] [datetime]$startDate, [Parameter(Mandatory=$True,Position=2)] [int]$Duration ) Write-Host $startDate Write-Host $Duration $holidays = @( (Get-Date -Date '2014-01-01'), # New_Years_Day2014 (Get-Date -Date '2014-01-20'), # Martin_Luther_King2014 (Get-Date -Date '2014-02-17'), # Washingtons_Birthday2014 (Get-Date -Date '2014-04-18'), # Good_Friday2014 (Get-Date -Date '2014-05-26'), # Memorial_Day2014 (Get-Date -Date '2014-07-04'), # Independence_Day2014 (Get-Date -Date '2014-09-01'), # Labor_Day2014 (Get-Date -Date '2014-11-27'), # Thanksgiving_Day2014 (Get-Date -Date '2014-12-25'), # Christmas2014 (Get-Date -Date '2015-01-01'), # New_Years_Day2015 (Get-Date -Date '2015-01-19'), # Martin_Luther_King2015 (Get-Date -Date '2015-02-16'), # Washingtons_Birthday2015 (Get-Date -Date '2015-04-03'), # Good_Friday2015 (Get-Date -Date '2015-05-25'), # Memorial_Day2015 (Get-Date -Date '2015-07-03'), # Independence_Day2015 (Get-Date -Date '2015-09-07'), # Labor_Day2015 (Get-Date -Date '2015-11-26'), # Thanksgiving_Day2015 (Get-Date -Date '2015-12-25') # Christmas2015 ) $dateIndex = $startDate.AddDays(1) [Int]$WorkingDays = 0 Write-Host "working days before counting" $WorkingDays For($DayIndex = 1; $DayIndex -le $Duration; $DayIndex++){ Write-Host "getting into for loop" Write-Host "day nr" $DayIndex Write-Host "date" $dateIndex Write-Host "duration" $Duration Do{ If (("Sunday","Saturday" -contains $dateIndex.DayOfWeek) -or ($holidays -contains $dateIndex)){ # This is not a working day. Check the next day. Write-Host "$($dateIndex.Date) is a $($dateIndex.DayOfWeek) and is weekend or holiday and it's a day no $DayIndex, working day no $WorkingDays" If (("Saturday" -contains $dateIndex.DayOfWeek) -or ($holidays -contains $dateIndex.AddDays(1))){ $DayIndex += 1 } $dateIndex = $dateIndex.AddDays(1) $isWorkingDay = $False } Else { # Current $dateIndex is a working day. If (!$isWorkingDay) { $DayIndex += 1 } $WorkingDays += 1 $isWorkingDay = $True Write-Host "$($dateIndex.Date) is a $($dateIndex.DayOfWeek) and is a working day and it's a day no $DayIndex, working day no $WorkingDays" Write-Host "Working days" $WorkingDays } } While(!$isWorkingDay) # Set the $dateIndex to the next day. $dateIndex = $dateIndex.AddDays(1) } # The last date was the end one. Minus the day. $dateIndex.AddDays(-1) Write-Host "Final working days $WorkingDays" Write-Output $WorkingDays }
问题原因
- PowerShell默认行为:未被赋值给变量、未被抑制输出的表达式,其结果会自动流入输出管道。
- 函数中
$dateIndex.AddDays(-1)这一行没有做任何处理,它的计算结果(一个datetime对象)会被输出到管道。 - 后续的
Write-Output $WorkingDays又输出了工作日数字,所以最终管道里有两个输出内容:日期对象和数字7,导致结果同时显示两者。
解决方法
你可以任选以下一种方式修正:
方式1:移除无用的日期计算行
如果这行代码只是调试遗留的,没有实际用途,直接删除$dateIndex.AddDays(-1)即可。
方式2:抑制该表达式的输出
如果需要保留这行代码(比如后续扩展功能时可能用到),可以通过以下方式阻止它输出到管道:
- 使用
[void]前缀:[void]$dateIndex.AddDays(-1) - 将结果管道到
Out-Null:$dateIndex.AddDays(-1) | Out-Null - 将结果赋值给一个临时变量(即使不用这个变量):
$tempDate = $dateIndex.AddDays(-1)
额外建议
函数中大量的Write-Host是调试输出,正式使用时建议移除,避免干扰最终的纯净输出。
内容的提问来源于stack exchange,提问作者Fiilli
相关产品推荐
相关产品推荐

