3

I've been looking for a PowerShell script similar to examples found in .NET examples. To take a New-TimeSpan and display is at 1 day, 2 hours, 3 minutes, 4 seconds. Exclude where its zero, add plural "s" where needed. Anybody have that handy?

This is as far as I got:

$StartDate = (Get-Date).ToString("M/dd/yyyy h:mm:ss tt")

Write-Host "Start Time: $StartDate"

# Do Something

$EndDate = (Get-Date).ToString("M/dd/yyyy h:mm:ss tt")

Write-Host "End Time: $EndDate" -ForegroundColor Cyan

$Duration = New-TimeSpan -Start $StartDate -End $EndDate
$d = $Duration.Days; $h = $Duration.Hours; $m = $Duration.Minutes; $s = $Duration.Seconds

Write-Host "Duration: $d Days, $h Hours, $m Minutes, $s Seconds"
TechFA
  • 129
  • 1
  • 9

2 Answers2

2

Why not doing it straight forward like this:

$StartDate = (Get-Date).AddDays(-1).AddMinutes(-15).AddSeconds(-3)
$EndDate = Get-Date

$Duration = New-TimeSpan -Start $StartDate -End $EndDate

$Day = switch ($Duration.Days) {
    0 { $null; break }
    1 { "{0} Day," -f $Duration.Days; break }
    Default {"{0} Days," -f $Duration.Days}
}

$Hour = switch ($Duration.Hours) {
    #0 { $null; break }
    1 { "{0} Hour," -f $Duration.Hours; break }
    Default { "{0} Hours," -f $Duration.Hours }
}

$Minute = switch ($Duration.Minutes) {
    #0 { $null; break }
    1 { "{0} Minute," -f $Duration.Minutes; break }
    Default { "{0} Minutes," -f $Duration.Minutes }
}

$Second = switch ($Duration.Seconds) {
    #0 { $null; break }
    1 { "{0} Second" -f $Duration.Seconds; break }
    Default { "{0} Seconds" -f $Duration.Seconds }
}

"Duration: $Day $Hour $Minute $Second"

Output would be :

Duration: 1 Day, 0 Hours, 15 Minutes, 3 Seconds

With 2 in each part of the duration ...

$StartDate = (Get-Date).AddDays(-2).AddHours(-2).AddMinutes(-2).AddSeconds(-2)

the result would be this:

Duration: 2 Days, 2 Hours, 2 Minutes, 2 Seconds

Of course you should wrap this in a function if you need it more than once. ;-)
And of course you can add more complex conditions if you like.

Olaf
  • 4,690
  • 2
  • 15
  • 23
  • I like this approach. How would I make it so days, hours and minutes don't display if they are zero? For example: Duration: 2 Hours, 30 Minutes, 10 Seconds or Duration: 30 Minutes, 10 Seconds or Duration: 10 Seconds. – TechFA Apr 26 '20 at 03:39
  • You just changed your question! ;-) ... but the answer would be the same. You check from days to minutes if the value is 0 and format the output accordingly. It might look weird when you have for example "15 hours and 235 milliseconds". Where are the minutes and seconds? Is it a failure? ;-) – Olaf Apr 26 '20 at 11:15
  • I guess I didn't word it appropriately, but I did say "Exclude where its zero". I agree it would look weird if middle time increments fell on the exact 0 hour, 0 minute so I would want to keep those and I don't care about milliseconds for this script. I'm a novice with PowerShell so how would I update your example to take the leading 0 days, 0 hours and 0 minutes out when they are 0? – TechFA Apr 26 '20 at 14:47
  • Hmmm ... ooops ... I actually missed that completely. ;-) ... but instead of complaining you could have started to try it yourself. Experience comes with practice. ;-) ... I changed the code. I commented out the cases where you omit the zero values. Just try it with or without. – Olaf Apr 26 '20 at 18:10
  • Thanks so much for your help, it's working great and I learned something in the process :) Sorry for the confusion on the initial question. – TechFA Apr 27 '20 at 02:22
2

The table view isn't bad:

new-timespan -Days 1 -Hours 1 -Minutes 1 -Seconds 1 | ft

Days Hours Minutes Seconds Milliseconds
---- ----- ------- ------- ------------
1    1     1       1       0
js2010
  • 23,033
  • 6
  • 64
  • 66