我有一个Powershell脚本,它可以获取当前时间并将其转换为Unix Timestamp。我想将此值用作字符串参数来发出HTTP请求:
$currentTime = [math]::Round([double](get-date -uformat %s ((get-date).AddMinutes(-5).ToUniversalTime()))*1000)
Invoke-RestMethod -Method Delete -Uri "http://something?unmodifiedSince=$currentTime"
在某些Windows机器上,它可以正常工作,但在其他(不同的Region设置?)上,我将当前时间转换为科学计数法。例如
http://something?unmodifiedSince=1.53835531189786E+17
如何避免这种转换?
答案 0 :(得分:1)
tl;博士:
要使用区域性特定的数字格式解决此问题,请在Get-Date -UFormat
结果上使用字符串替换以确保小数点分隔符为.
,这是[double]
强制转换所要求的:
[math]::Round([double] (
(get-date -uformat %s ((get-date).AddMinutes(-5).ToUniversalTime())) -replace
'[^\d]', '.') * 1000
)
-replace '[^\d]', '.'
替换非数字字符。与.
,以及唯一的非数字字符。在Get-Date -UFormat %s
的输出中,是区域性特定的小数点。
实际上,您的问题源于以下事实:
Get-Date -UFormat %
输出Unix时间戳的 string 表示形式'1538651788,87456'
作为小数点)而不是,
作为输出。相比之下,PowerShell的强制转换始终使用不变文化,其中仅将'1538651788.87456'
识别为小数点-并忽略.
,这被认为是上千个分组的字符。
,
因为忽略了小数点标记并且有5个小数位,所以在这种情况下,结果数太大了10,000倍(尽管请注意,由于不显示尾随零,所以小数位数可能会有所不同)
如果将结果乘以1000,则会得到一个很大的数字,因此PowerShell会将其字符串表示形式默认为您经历过的科学格式:
PS> [double] '1538651788,87456'
153865178887456 # !! , was IGNORED
[1]可选阅读:Windows PowerShell与PowerShell Core中的PS> [double] '1538651788,87456' * 1000
1.53865178887456E+17 # !! scientific notation.
问题:
Unix时间戳是 integers ,因此Get-Date -UFormat %s
不应以浮点数开头。此问题已在PowerShell Core 中得到纠正。
Unix时间戳以UTC表示,但是 Windows PowerShell仅在您显式传递UTC Get-Date -UFormat %s
实例时才返回正确的值。在PowerShell Core 中,此问题已得到纠正。
[datetime]
还不够;改用Get-Date -UFormat %s
。简而言之:在PowerShell Core 中不会出现此问题的问题,因为 integers 的字符串表示形式不区分文化;此外,舍入的需求消失了,将输入日期转换为UTC的需求也消失了,因此PowerShell Core解决方案简化为:
Get-Date -UFormat %s ([datetime]::UtcNow)
答案 1 :(得分:1)
我使用这个小函数来获取当前的日期和时间,作为Unix时间戳。 它返回一个int64,因此您可以毫不费力地将其添加到url中:
function Get-CurrentUnixTimeStamp {
[DateTime]$epoch = New-Object System.DateTime 1970, 1, 1, 0, 0, 0, 0, Utc
[TimeSpan]$diff = (Get-Date).ToUniversalTime() - $epoch
return [int64][Math]::Floor($diff.TotalSeconds)
}
$currentTime = Get-CurrentUnixTimeStamp
Invoke-RestMethod -Method Delete -Uri "http://something?unmodifiedSince=$currentTime"
答案 2 :(得分:-1)
您可以将$currentTime
变量数据类型显式表示为[Decimal]
,而不是自动分配的[Double]
。像这样:
[Decimal]$currentTime = [math]::Round([double](get-date -uformat %s ((get-date).AddMinutes(-5).ToUniversalTime()))*1000)