Формат файла Powershell Продолжительность как часы и минуты

50
6

Я пытаюсь отформатировать вывод строки TimeSpan в виде $h Hours $m Minutes, учитывающий плюрализацию. Прямо сейчас, у меня есть код ниже, который работает очень хорошо; однако, когда он встречает TimeSpan менее часа, он отображает его как 0 $m minutes.

Function FormatDuration ([TimeSpan]$Duration) {
[string]$DurationStr = [math]::floor($Duration.TotalMinutes/60).ToString()
if ([math]::floor($Duration.TotalMinutes/60) -eq 1) {
$DurationStr = $DurationStr+" hour"
} elseif ([math]::floor($Duration.TotalMinutes/60) -ne 0) {
$DurationStr = $DurationStr+" hours"
}
if ($Duration.Minutes -eq 1){
$DurationStr = $DurationStr+" "+$Duration.Minutes+" minute"
# Does not display minutes if value is 0
} elseif ($Duration.Minutes -ne 0) {
$DurationStr = $DurationStr+" "+$Duration.Minutes+" minutes"
}
return $DurationStr
}

Я попытался найти, если кто-то другой решил эту проблему, но ближайшим, которого я смог найти, было решение zuallauz в этом потоке С#.

К сожалению, кажется, что TimeSpans ведут себя по-разному в Powershell, где они будут отображать дни и часы отдельно, то есть TimeSpan 25 часов и 45 минут будет храниться как:

New-TimeSpan -Hours 25 -Minutes 45

Days : 1
Hours : 1
Minutes : 45
Seconds : 0
Milliseconds : 0
Ticks : 927000000000
TotalDays : 1.07291666666667
TotalHours : 25.75
TotalMinutes : 1545
TotalSeconds : 92700
TotalMilliseconds : 92700000

Может ли кто-нибудь указать мне в правильном направлении, как решить эту проблему? Мои первые мысли - отделить обработку часов и минут, а затем объединить их в конце, а не в каждом операторе if-else.

Редактировать:

С помощью решения Sambardo я смог создать следующую функцию:

Function FormatDuration ([TimeSpan]$Duration) {
$h = $Duration.Days * 24 + $Duration.Hours
$m = $Duration.Minutes

switch ($h) {
0 {$HourStr=$null}
1 {$HourStr="$h hour"}
{$_ -ge 1} {$HourStr="$h hours"}
}
switch ($m) {
0 {$MinuteStr=$null}
1 {$MinuteStr="$m minute"}
{$_ -ge 1} {$MinuteStr="$m minutes"}
}
if ($HourStr -gt 0 -and $MinuteStr -gt 0) {
[String]$DurationStr=$HourStr+" "+$MinuteStr
} else {
$DurationStr=$HourStr+$MinuteStr
}

return $DurationStr
}

Спасибо за вашу помощь!

спросил(а) 2018-04-04T23:24:00+03:00 1 год, 10 месяцев назад
1
Решение
50

Может быть, я что-то пропустил о вашем вопросе, но почему бы не просто отвести дни до часов, а затем проверить, больше ли часов, чем 0, чтобы настроить строку?

$TimeSpan = New-TimeSpan -Minutes 45
$h = $TimeSpan.Days * 24 + $TimeSpan.Hours
$m = $TimeSpan.Minutes
if($h -gt 0){"$h hours $m minutes"}
else{"$m minutes"}

ответил(а) 2018-04-04T23:33:00+03:00 1 год, 10 месяцев назад
49

Function FormatDuration ([TimeSpan]$Duration) {
$DurHours = [math]::floor($Duration.TotalHours)
$DurMins = $Duration.Minutes
if ($DurHours-1){$PlHours='s'} else {$PlHours=''}
if ($DurMins -1){$PlMins='s'} else {$PlMins=''}
return "{0} hour$($PlHours) {1} minute$($PlMins)" -f $DurHours,$DurMins
}

FormatDuration (New-TimeSpan -Hours 25 -Minutes 45)
FormatDuration (New-TimeSpan -Hours 1 -Minutes 45)
FormatDuration (New-TimeSpan -Hours 1 -Minutes 1)
FormatDuration (New-TimeSpan -Hours 0 -Minutes 1)

Пример вывода:

25 hours 45 minutes
1 hour 45 minutes
1 hour 1 minute
0 hours 1 minute

ответил(а) 2018-04-05T01:35:00+03:00 1 год, 10 месяцев назад
51

Просто добавьте условие else в конце. Если значение "Пол" не равно 1 и не отличается от нуля, единственное возможное значение, оставшееся для этажа, равно нулю. Таким образом, в вашем else вы можете управлять нулевым значением, гася строку.

if ([math]::floor($Duration.TotalMinutes/60) -eq 1) {
$DurationStr = $DurationStr+" hour"
} elseif ([math]::floor($Duration.TotalMinutes/60) -ne 0) {
$DurationStr = $DurationStr+" hours"
} else {
$DurationStr = ""
}

ответил(а) 2018-04-04T23:59:00+03:00 1 год, 10 месяцев назад
49

Немного надоедливо сделать, чтобы он выглядел красиво, как вы этого хотите, но это выполнит ваш запрос.

$Duration = New-TimeSpan -Hours 25 -Minutes 1
$TotalHours = $Duration.Hours + ( $Duration.Days * 24 )

$String = "$TotalHours Hour"
if ( $TotalHours -gt 1 )
{
$String += 's'
}
$String += " $($Duration.Minutes) Minute"
if ( $Duration.Minutes -gt 1 )
{
$String += 's'
}

return $String

Возвращает значение

25 Hours 1 Minute

ответил(а) 2018-04-04T23:45:00+03:00 1 год, 10 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема