tl; dr :
Чтобы обойти проблему с форматированием чисел, зависящим от культуры, используйте замена строки в результате 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 %
выводит string представление метки времени Unix - и использует чувствительное к культуре форматирование для базового числа с плавающей точкой [1] , что означает, что в некоторыхв культурах вы получите строку, например
'1538651788,87456'
(,
в качестве десятичной метки), а не '1538651788.87456'
в качестве выходного.
В отличие от этого, при преобразовании PowerShell всегда используется инвариант культура, который только распознает .
как десятичную метку - и игнорирует ,
, который считается символом группировки тысяч.
PS> [double] '1538651788,87456'
153865178887456 # !! , was IGNORED
Поскольку десятичная дробьМетка была проигнорирована, и есть 5 десятичных знаков, в этом случае результирующее число слишком велико в 10 000 раз (хотя учтите, что число десятичных знаков может варьироваться, поскольку завершающие нули не отображаются).
Если затем умножить это результатt с 1000, вы получите такое большое число, что PowerShell по умолчанию будет представлять его строковое представление в научном формате:
PS> [double] '1538651788,87456' * 1000
1.53865178887456E+17 # !! scientific notation.
[1] Дополнительное чтение: Get-Date -UFormat %s
проблемы в Windows PowerShell и PowerShell Core:
Временные метки Unix целые , поэтому Get-Date -UFormat %s
не должно возвращать число с плавающей запятой для началас.Эта проблема была исправлена в PowerShell Core .
Отметки времени Unix выражены в UTC, но Windows PowerShell возвращает правильное значение, только если вы явно передаетеUTC [datetime]
экземпляр .Эта проблема была исправлена в PowerShell Core .
- Например, чтобы получить метку времени Unix текущего времени в Windows PowerShell, используя
Get-Date -UFormat %s
- not достаточно;вместо этого используйте Get-Date -UFormat %s ([datetime]::UtcNow)
.
Вкратце: проблема этого вопроса не возникла бы в PowerShell Core , потому что строкапредставления целых чисел не чувствительны к культуре;Кроме того, отпадает необходимость округления, равно как и необходимость преобразования входной даты в UTC, так что решение PowerShell Core упрощается до:
# PowerShell *Core* only
[double](get-date -uformat %s ((get-date).AddMinutes(-5))) * 1000