Добавьте Sexagesimal раз в PowerShell - PullRequest
0 голосов
/ 26 ноября 2018

Я использую ffprobe, чтобы получить половинное минимальное время, и после усечения последних трех (ненужных) цифр я получаю следующий формат:

#examples
 0:05:51.15 
11:03:15.24

Есть ли способ добавить эти 2 так, чтобырезультат 11:09:06.39?

1 Ответ

0 голосов
/ 26 ноября 2018

Вы можете привести строки к типу [timespan], что позволяет выполнять арифметику с результирующими объектами и применять пользовательское форматирование к выводу:

PS> ([timespan] ' 0:05:51.15' + [timespan] '11:03:15.24').ToString('h\:mm\:ss\.ff')
11:09:06.39

Примечание:Если существует вероятность того, что результирующий промежуток времени превысит 24 часа, потребуется больше работы. [1]

Обратите внимание, как \ -escaping должен использоваться для указания выводаразделители в качестве литералов .
В этом случае более простой .ToString('g') дал бы тот же результат, но только в культурах, которые используют . в качестве десятичного разделителя , поскольку стандартный спецификатор формата g является чувствительным к культуре .См. [timespan]::ToString() документацию , а также документацию по стандартным и пользовательским спецификаторам формата времени.

Для контраста, PowerShell использует инвариантную культуру при интерпретации формата ввода , приведенного к [timespan], где . - десятичный разделитель;аналогично, использование [timespan] instance в раскрываемых строках дает представление, инвариантное к культуре;Например:

  • [timespan] '11:03:15.24' всегда работает, независимо от текущей культуры, потому что инвариантная культура ожидает . в качестве десятичного разделителя.
  • "$([timespan] '1' - 1)" всегда дает 23:59:59.9999999, независимо от текущей культуры [2] .

As Нет возврата Нет возврата примечания,если вы имеете дело с вводом в другом формате , возможно из другой культуры , вы можете использовать [timespan]::Parse() / [timespan]::ParseExact()/ [timespan]::TryParseExact()


Разбор стандартных форматов данной культуры :

[timespan]::Parse(' 0:05:51,15', 'fr-FR') # OK

Примечание, в качестве десятичного разделителя.

Если вы опускаете аргумент культуры (или передаете $null), применяется культура current .Обратите внимание, как это отличается от использования [timespan] cast , который всегда является инвариантом для культуры (и принимает . в качестве десятичного разделителя).


Разбор с пользовательским форматом:

[timespan]::ParseExact(' 0:05:51,15'.Trim(), 'h\:mm\:ss\,ff', $null) # OK

Обратите внимание, что при использовании такой буквальный пользовательский формат никогда чувствительный к культуре , потому что все разделители должны быть указаны как - escape-литералы (например, \:), поэтому $null передается в качестве аргумента культуры (IFormatProvider).
И наоборот, передача определенной культуры имеет смысл только с чувствительными к культуре спецификаторами формата standard , g и G.

Анализ с помощью настраиваемый с учетом культуры пользовательский формат:

Если вы не знаете, какая культура будет действовать во время выполнения, но хотите соблюдать десятичный разделитель этой культуры в сочетании спользовательский формат , вам нужно динамически вставлять десятичный разделитель текущей культуры в ваш пользовательскийстрока формата :

$tsText = ' 0:05:51.15'
[timespan]::ParseExact($tsText.Trim(), 
  ('h\:mm\:ss\{0}ff' -f [cultureinfo]::CurrentCulture.NumberFormat.NumberDecimalSeparator),
  $null
) # OK in cultures that use "." as the decimal separator

[1] h и hh отражают только часы , не включенные в полные дни во входных данныхпромежуток времени.Чтобы отразить количество дней также, добавьте что-то вроде d\. - есть спецификатор формата no , который позволяет вам выразить общее количество часов в течение нескольких дней , но вы можете использовать общие-целевое форматирование строки для достижения этого - однако учтите, что вам также понадобится пользовательский код синтаксического анализа , чтобы преобразовать полученную строку обратно в [timespan] экземпляр:
$ts = [timespan] ' 1:05:51.15' + [timespan] '23:03:15.24'
'{0}:{1:mm\:ss\.ff}' -f [Math]::Floor($ts.TotalHours), $ts

[2] На уровне .NET вызов .ToString() для объектов обычно приводит к представлению чувствительного к культуре (если тип поддерживает его), но с[timespan] результат оказывается не зависящим от культуры.В отличие от этого, PowerShell явно использует инвариантную культуру за кулисами в приведениях и интерполяции строк, так что "$var" и $var.ToString() могут не давать то же самоепредставление - см. этот ответ для деталей.

...