我正在用Bash翻译PowerShell脚本。
在PowerShell中获取当前日期时间的刻度:
[System.DateTime]::Now.Ticks;
通过遵循Ticks的定义,下面是我在bash中使用date
命令近似计算的方法:
echo $(($(($(date -u '+%s') - $(date -d "0001-01-01T00:00:00.0000000 UTC" '+%s'))) * 10000000 ))
这是我最后一次尝试得到的结果:
$ echo $(($(($(date -u '+%s') - $(date -d "0001-01-01T00:00:00.0000000 UTC" '+%s'))) * 10000000 )) ; pwsh -c "[System.DateTime]::Now.Ticks;"
637707117310000000
637707189324310740
特别是,前7位数字是相同的,但位置8和9的数字在两个值之间仍然相差太大。
我计算出这意味着两个值之间只有2小时的差异。但是为什么呢?它不可能是时区,因为我在两个date
命令中都指定了UTC时区,对吗?你觉得呢?
注意:我对时区的怀疑正在增加,因为我目前基于UTC+2(因此与UTC相差2小时),但这怎么可能,因为我在date
命令中显式指定UTC作为时区?
解决了!问题不在于date
命令,而在于PowerShell命令,它使用的是+2时区(CEST时间)。为了解决这个问题,我现在使用UtcNow
而不是Now
。
这是我现在得到的:
$ echo $(($(($(date -u '+%s') - $(date -d "0001-01-01T00:00:00.0000000 UTC" '+%s'))) * 10000000 )) ; pwsh -c "[System.DateTime]::UtcNow.Ticks;"
637707132410000000
637707132415874110
正如你所看到的,现在所有的数字都是相同的,除了最后7位数字,因为我故意添加了零来从秒转换为滴答,因为我对秒的分数不感兴趣(现在),我认为它们可以忽略不计。
替代方式另一种使两个值相同(仍然不包括秒的部分)的方法是,在第一个date
命令中删除-u
选项以使用当前时区,并在第二个date
命令中将UTC
替换为+0200
。如果我这样做,我可以把Now
留在PowerShell命令(而不是用UtcNow
代替它)。
通过这样做,我得到:
$ echo $(($(($(date '+%s') - $(date -d "0001-01-01T00:00:00.0000000 +0200" '+%s'))) * 10000000)) ; pwsh -c "[System.DateTime]::Now.Ticks;"
637707218060000000
637707218067248090
如果你还想要秒的分数
我刚刚明白,如果您还需要考虑秒的分数,那么您只需要将date '+%N'
(纳秒)除以100的结果添加到计算中,在上面显示的两种方法中的任何一种。
由于date '+%N'
的结果可能有一些前导零,Bash可能认为它是一个八进制值。为了避免这种情况,只需在10#
前面显式地表示它是一个十进制值。
$ echo $(($(($(date '+%s') - $(date -d "0001-01-01T00:00:00.0000000 +0200" '+%s'))) * 10000000 + $((10#$(date '+%N')/100)) ))
637707225953311420