c# - 为什么我在 Powershell 和 C# 之间得到不同的结果

标签 c# powershell datetime bit-shift

我有一个将日期时间转换为 DOS 格式的方法

它最初是用 C# 编写的,但我已将其转换为 powershell。

两者的相同输入返回不同的结果。 我正在努力寻找原因。

Powershell 方法

Function ConvertTo-DOSDate {
    Param(
        [DateTime]$dateTime

    )

    Process {
        Try {

            [int] $ret = (($dateTime.Year - 1980) -band 0x7F);
            $ret = ($ret -shl 4) + $dateTime.Month;
            $ret = ($ret -shl 5) + $dateTime.Day;
            $ret = ($ret -shl 5) + $dateTime.Hour;
            $ret = ($ret -shl 6) + $dateTime.Minute;
            $ret = ($ret -shl 5) + ($dateTime.Second / 2); # only 5 bits for second, so we only have a granularity of 2 sec.
            return  [uint32] $ret;

        }
        Catch {

            throw "Exception: $_"
        }
    }

}

C#方法

  public static uint DateTimeToDosTime(DateTime dateTime)
        {
            // DateTime must be Convertible to DosTime:
            //#Debug.Assert(ValidZipDate_YearMin <= dateTime.Year && dateTime.Year <= ValidZipDate_YearMax);

            int ret = ((dateTime.Year - 1980) & 0x7F);
            ret = (ret << 4) + dateTime.Month;
            ret = (ret << 5) + dateTime.Day;
            ret = (ret << 5) + dateTime.Hour;
            ret = (ret << 6) + dateTime.Minute;
            ret = (ret << 5) + (dateTime.Second / 2); // only 5 bits for second, so we only have a granularity of 2 sec.
            return (uint)ret;
        }

在我运行的 powershell 控制台中:

Add-Type -Path "C:\temp\ClassLibrary1.dll"
$date = New-Object DateTime 2019, 08, 30, 20, 56, 43 
$powershellResult = ConvertTo-DOSDate -dateTime $date 
$CSharpResult = [TomLib.ZipHelper]::DateTimeToDosTime($date)

write-host "Input Date : $date"
Write-host "Powershell: $powershellResult"
write-host "C#: $CSharpResult"

然后输出

Input Date : 08/30/2019 20:56:43
Powershell: 1327408918
C#: 1327408917

最佳答案

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_arithmetic_operators?view=powershell-6说:

DIVISION AND ROUNDING When the quotient of a division operation is an integer, PowerShell rounds the value to the nearest integer. When the value is .5, it rounds to the nearest even integer.

The following example shows the effect of rounding to the nearest even integer.

Expression  Result
[int]( 5 / 2 )  2
[int]( 7 / 2 )  4

Notice how 5/2 = 2.5 gets rounded to 2. But, 7/2 = 3.5 gets rounded to 4.

当 C# 在 int 空间中进行除法时,它只删除小数部分:

5/2 -> 2, 
7/2 -> 3

在 powershell 中,您的示例时间的秒分量为 43,因此 43/2 向上舍入为 22,这是最接近的偶数

在 C# 中 43/2 是 21

这会在您的结果中引入一个错误,因为在 C# 形式中您正在执行 ret+21 而在 powershell 形式中您是 $ret+22

关于c# - 为什么我在 Powershell 和 C# 之间得到不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57732746/

相关文章:

function - 函数将值返回到控制台,但不返回到文件

powershell - 无法设置 AzureRmKeyVaultAccessPolicy

python - Django - 需要只能处理年份或年份和月份值的日期时间字段

c# - MVC 中使用 Post 方法重定向到 Action

powershell - 导入 IP 地址列表、解析其主机名、将 IP 和主机名导出到电子表格

c# - 如何使用 C# 从当前日期获取当前季度

ruby-on-rails - 在 Rails 或一般的 Ruby 中,我如何知道日期时间字符串是否对应于具有 DST 或不具有 DST 的日期时间?

python 3.7 : converting a string with different timezone into date

c# - 代码分析不显示 CA1804 警告,尽管在 C# 中未使用本地字符串变量 (VS2010 Premium)

c# - 公开强类型列表?