在Powershell中添加六倍体时间

时间:2018-11-26 01:48:59

标签: powershell timespan ffprobe

我正在使用ffprobe来获取十六进制的时间,并且在修整了最后三位(不必要的)数字后,我得到了以下格式:

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

有没有一种方法可以将这两个数相加,使结果为11:09:06.39

1 个答案:

答案 0 :(得分:3)

您可以强制转换字符串以键入[timespan] ,这使您可以对所得对象执行算术运算,并在输出中应用自定义格式:

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

注意:如果结果时间跨度超过24小时,则需要做更多的工作。 [1]

请注意必须如何使用 \-转义来将输出分隔符指定为文字
在这种情况下,更简单的.ToString('g')会产生相同的输出,但是仅在使用.作为小数分隔符的区域性中,因为标准的g格式说明符对文化敏感。 请参阅[timespan]::ToString() documentation以及有关standardcustom时间跨度格式说明符的文档。

相反, PowerShell在解释输入格式时使用invariant culture 强制转换为[timespan],其中.是小数点分隔符;类似地,使用{em>扩展字符串中的[timespan]实例 产生文化不变的表示形式;例如:

  • [timespan] '11:03:15.24' 始终有效,与当前的区域性无关,因为不变的区域性期望.作为小数点分隔符。
  • "$([timespan] '1' - 1)" 始终产生23:59:59.9999999,与当前的文化形式 [2] 无关。

No Refunds No Returns所述,如果您使用格式不同的输入进行交易,可能来自不同的文化,则可以使用[timespan]::Parse() / [timespan]::ParseExact() / [timespan]::TryParseExact()


解析给定文化的标准格式

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

请注意,作为小数点分隔符。

如果您省略文化参数(或通过$null),则将应用当前文化。请注意,这与使用[timespan] cast (始终为区域性-不变)(并假设.为小数分隔符)有何不同。


使用自定义格式进行解析:

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

请注意,使用这样的文字 custom 格式是从不区分文化的,因为所有分隔符必须指定为-转义-文字(例如\:),因此将$null作为文化参数(IFormatProvider)传递。
相反,仅通过对文化敏感的 standard 格式说明符gG来传递特定的文化才有意义。

使用一种可识别文化的自定义格式进行解析:

如果您不知道在运行时会采用哪种区域性,但是您想尊重该区域性的小数点分隔符和自定义格式,则需要动态嵌入您的自定义格式字符串中当前区域性的小数点分隔符

$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] hhh仅反映输入时间跨度中整整天未包含的小时数 。为了反映天数,还可以使用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()可能不是产生相同的表示形式-有关详细信息,请参见this answer