Powershell 毕业年份计算在减去 -2 时中断

Powershell Year of Graduation Calculation Breaks When Subtracting -2

我必须根据年级推断学生的毕业年份。他们的学生证号码中有 2 位数的毕业年份,但由于学生被推迟和其他基于身份证号码的异常情况,这有时被证明是不准确的。

我写了一个 powershell 脚本来为我做这件事,作为一个更大的脚本的一部分,用于获取从 powerschool 导出的 CSV,并根据他们的毕业年份检查他们在活动目录中的位置。我遇到问题的脚本部分如下:

function GradeToYog($grade){ # converts grade number to year of grad because IDNUM is not a reliable indicator of grad year
    if($grade -ne $null){
        # get current date
        $date = Get-Date

        # account for time of year, add 1yr offset to grad year if september or later
        $offset = 0
        if($date.month -ge 9){
            $offset = 1
        }

        # Account for placement of extended-stay students such as SPED kids
        if($grade -gt 12){
            $grade = 12
        }

        return ($date.year + 12 + $offset - $grade)    
    } else {
        return "Invalid entry."
    }
}

这适用于 -1 年级(学前班)到 12 年级,但是当我针对 -2 测试它时它会中断:

PS C:\> GradeToYog 12
2022
PS C:\> GradeToYog 9
2025
PS C:\> GradeToYog 6
2028
PS C:\> GradeToYog 3
2031
PS C:\> GradeToYog 1
2033
PS C:\> GradeToYog 0
2034
PS C:\> GradeToYog -1
2035
PS C:\> GradeToYog -2
2022

奇怪的是,如果我在 powershell 中根据相同的逻辑测试预期值,它会起作用:

PS C:\> 2022 + 12 + 0 - -2
2036

我搜索了类似的问题,但要么我没有正确搜索它,要么似乎没有 powershell 错误地减去 '-2' 的实例

注意:我无法重现您的具体症状,但以下建议仍然值得听取。


Type-constrain 你的 $grade 参数确保它是一个 number:

# Make sure that $grade is an [int] (System.Int32) value
function GradeToYog([int] $grade) { # ...

# Alternative syntax, with a param(...) block,
# which makes it easier to use validation attributes.
function GradeToYog {
  param(
    [ValidateRange(-2, 15)] # Constrain the range of allowable numbers.
    [int] $grade
  )
  # ...
}

无约束参数实际上与[object] $grade相同,即它可以接收任何类型的对象。

PowerShell 推断 某些类型来自未加引号的参数,例如 2-2,也许令人惊讶的是,2 变成了 [int],而 -2 变为 [string](强制后者被解释为 [int] ad hoc,将其作为 (-2)).

许多 PowerShell 运算符,例如 -eq / ne-lt / -le / -gt / ge 都可以同时运行字符串和数字,通常是 LHS 操作数的类型决定了整个操作的数据类型。

这是一个例子,说明这会产生什么影响:

2 -lt 10    # $true
'2' -lt 10  # !! $false, due to *lexical* comparison