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 %
выводит строковое представление временной метки Unix.
- и использует форматирование с учетом языка и региональных параметров для базового числа с плавающей запятой [1], что означает, что в некоторых культурах вы получите строку, например
'1538651788,87456'
(,
в качестве десятичный знак), а не '1538651788.87456'
в качестве вывода.
Напротив, приведения PowerShell всегда используют инвариантный язык и региональные параметры, который только распознает .
как десятичный знак и игнорирует ,
, который считается символом группировки тысяч.
PS> [double] '1538651788,87456'
153865178887456 # !! , was IGNORED
Поскольку десятичная метка была проигнорирована и имеется 5 десятичных знаков, результирующее число в этом случае будет слишком большим в 10 000 раз (хотя обратите внимание, что количество десятичных знаков может варьироваться, поскольку конечные нули не отображаются).
Если вы затем умножите этот результат на 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.
- E.g., to get the current time's Unix timestamp in Windows PowerShell, using
Get-Date -UFormat %s
is not enough; use Get-Date -UFormat %s ([datetime]::UtcNow)
instead.
Вкратце: проблема этого вопроса не возникла бы в PowerShell Core, потому что строковое представление целых чисел не зависит от языка и региональных параметров; Кроме того, отпадает необходимость в округлении, как и в преобразовании даты ввода в UTC, так что решение PowerShell Core упрощается до:
# PowerShell *Core* only
[double](get-date -uformat %s ((get-date).AddMinutes(-5))) * 1000
person
mklement0
schedule
04.10.2018