My function, Get-TimespanPretty, allows you to view the time span—the difference between two time points or dates—in a compact, user-friendly format. It is built on top of the New-TimeSpan cmdlet, which offers details as output that you usually need. With Get-TimespanPretty, you can simply pipe the output (TimeSpan object) of New-TimeSpan or Measure-Command to Get-TimespanPretty. It's easy to use, and there's no need for complex reworking of scripts that may include such commands.
Avatar

My function displays the number of weeks, days, hours, minutes, and seconds. For short time spans, Prerequisites

My function works with any version of PowerShell that supports the PowerShell New-Timespan cmdlet. Basically, this means that any currently available PowerShell version is supported. You can test whether New-Timespan is available on your system like this:

Get-Command New-TimeSpan
Testing support for Get TimeSpanPretty

Testing support for Get TimeSpanPretty

If you receive an output like in the screenshot above, you can use Get-TimespanPretty.

Examples

Let's see Get-TimespanPretty in action. I like to learn by example. For more details and a formal description of the function, you can run Get-Help, as shown below.

Get-Help Get-TimeSpanPretty

or

Get-Help Get-TimeSpanPretty -Examples

Use with New-TimeSpan

Simply pipe the output of New-TimeSpan to Get-TimespanPretty to get a simpler, prettier format for the time interval. In the example below, you'll first see the original output, and then you'll get the more human-friendly format created by my function.

New-TimeSpan -Start "2022-09-15 14:55" -End "2022-10-05 11:20:05"
New-TimeSpan -Start "2022-09-15 14:55" -End "2022-10-05 11:20:05" | Get-TimeSpanPretty
Get TimeSpanPretty provides a more concise way to view a time interval

Get TimeSpanPretty provides a more concise way to view a time interval

Measure the execution time of a script with New-TimeSpan

As before, you can use New-TimeSpan to measure the time it took to run one or more PowerShell commands. This can be very useful for measuring scripts that need to run a long time to complete their task.

$StartTime = Get-Date

# your (long-running) commands go here
# Optimize-VHD -Path C:\VMs\FS1-UserData.vhdx -Mode Full
# Get-Aduser -Filter {Department -like "*Manager*"} | Remove-ADUser -Confirm:$false

$EndTime = Get-Date

New-TimeSpan -Start $StartTime -End $EndTime | Get-TimeSpanPretty 
Measuring the time it takes to run a PowerShell command

Measuring the time it takes to run a PowerShell command

As you can see in the screenshot above, it took the PowerShell script one minute and 48 seconds to complete the task.

Measure the execution time of a script with Measure-Command

Another way to measure the execution time of a script is to use Measure-Command. As before, I'll pipe the output to Get-TimespanPretty.

Measure-Command {Get-Service | foreach {Start-Sleep -Milliseconds 15}} 
Measure-Command {Get-Service | foreach {Start-Sleep -Milliseconds 15}} | Get-TimeSpanPretty 
Another way to measure the duration of one or more commands

Another way to measure the duration of one or more commands

As in the previous example, you first see the raw output and then the human-friendly version created by my function.

The Get-TimespanPretty function

Below, you'll find the complete code for my Get-TimespanPretty function. Instead of playing the copy-and-paste game every time you need it, you can include it in your PowerShell profile script or in a module.

Subscribe to 4sysops newsletter!

Function Get-TimeSpanPretty {
<#
.Synopsis
   Displays the time span between two dates in a single line, in an easy-to-read format
.DESCRIPTION
   Only non-zero weeks, days, hours, minutes and seconds are displayed.
   If the time span is less than a second, the function display "Less than a second."
.PARAMETER TimeSpan
   Uses the TimeSpan object as input that will be converted into a human-friendly format
.EXAMPLE
   Get-TimeSpanPretty -TimeSpan $TimeSpan
   Displays the value of $TimeSpan on a single line as number of weeks, days, hours, minutes, and seconds.
.EXAMPLE
   $LongTimeSpan | Get-TimeSpanPretty
   A timeline object is accepted as input from the pipeline. 
   The result is the same as in the previous example.
.OUTPUTS
   String(s)
.NOTES
   Last changed on 28 July 2022
#>

    [CmdletBinding()]
    Param
    (
        # Param1 help description
        [Parameter(Mandatory,ValueFromPipeline)][ValidateNotNull()][timespan]$TimeSpan
    )

    Begin {}
    Process{

        # Initialize $TimeSpanPretty, in case there is more than one timespan in the input via pipeline
        [string]$TimeSpanPretty = ""
    
        $Ts = [ordered]@{
            Weeks   = [math]::Floor($TimeSpan.Days / 7)
            Days    = [int]$TimeSpan.Days % 7
            Hours   = [int]$TimeSpan.Hours
            Minutes = [int]$TimeSpan.Minutes
            Seconds = [int]$TimeSpan.Seconds
        } 

        # Process each item in $Ts (week, day, etc.)
        foreach ($i in $Ts.Keys){

            # Skip if zero
            if ($Ts.$i -ne 0) {
                
                # Append the value and key to the string
                $TimeSpanPretty += "{0} {1}, " -f $Ts.$i,$i
                
            } #Close if
    
        } #Close for
    
    # If the $TimeSpanPretty is not 0 (which could happen if start and end time are identical.)
    if ($TimeSpanPretty.Length -ne 0){

        # delete the last coma and space
        $TimeSpanPretty = $TimeSpanPretty.Substring(0,$TimeSpanPretty.Length-2)
    }
    else {
        
        # Display "Less than a second" instead of an empty string.
        $TimeSpanPretty = "Less than a second"
    }

    $TimeSpanPretty

    } # Close Process

    End {}

} #Close function Get-TimeSpanPretty

Summary

My function, Get-TimeSpanPretty, gives you a quick and easy way to convert TimeSpan objects into a user-friendly format. You can include it in your scripts or PowerShell-generated reports for better-looking output.

avatar
8 Comments
  1. Avatar
    cK 1 year ago

    this seem not so correct. the week.

    • Avatar Author

      Hi, cK. Can you please share an example where this didn’t work?
      Cheers. Emanuel

      • Avatar
        Oz Edri 1 year ago

        In the screenshot of the first example under the “Use with New-TimeSpan ” section the first command got one (right) output, and the second command got another. For example, the first one returned 19 days, while the second one returned 3 weeks and 5 days.

        • Avatar Author

          Hi, Oz Edri. Indeed, I didn’t think to always floor the “weeks” to a round number instead of leaving it as a round number. This meant that my function was always adding up a week when the time-span was n weeks and a half (wrongly displaying n+1 weeks). I’ve corrected it. Thanks for pointing it up, and apologies for the omission.

    • Avatar Author

      Hi, cK. I think I figured out where the mistake was, thanks to Oz Edri who pointed me in the right direction (see comment above). I hope it’s fine now for you.

  2. Avatar
    s31064 1 year ago

    Very nice, thank you. I was timing my scripts with

    $stopWatch = New-Object System.Diagnostics.Stopwatch
    $stopWatch.Start()
    # Script code goes here
    $CheckTime = $stopWatch.Elapsed
    if ($CheckTime.Days -gt ‘0’)
    {
    Write-Verbose $(“Script Completed in {0} days, {1} hours, {2} minutes`n” -f $CheckTime.Days, $CheckTime.Hours, $CheckTime.Minutes )
    }
    elseif ($CheckTime.Hours -gt ‘0’)
    {
    Write-Verbose $(“Script Completed in {0} hours, {1} minutes`n” -f $CheckTime.Hours, $CheckTime.Minutes )
    }
    elseif ($Checktime.Minutes -gt ‘0’)
    {
    Write-Verbose $(“Script Completed in {0} minutes, {1} seconds`n” -f $CheckTime.Minutes, $CheckTime.Seconds )
    }
    else
    {
    Write-Verbose $(“Script Completed in {0} seconds, {1} milliseconds, {2} ticks`n” -f $CheckTime.Seconds, $CheckTime.Milliseconds, $CheckTime.Ticks )
    }

    I still use stopwatch, but I’ve replaced all of the if, elseif, else at the end with a simple

    $CheckTime = $stopWatch.Elapsed
    “Script took $($CheckTime | Get-TimeSpanPretty).”
    $stopWatch.Stop()

    Much neater and pretty much exactly the same information. Good job.

    • Avatar
      s31064 1 year ago

      Sorry, I always forget the pre tags.

    • Avatar Author

      Hello, s31064 (wow, nice name, you could pretend to be one of Elon Musk’s children and claim inheritance money :D)

      I’m glad you find this useful. Basically, i tried to make something that makes life easier. It’s a short one-liner once you’ve referenced the function, so my scripts look clearer.
      I’m even happier when others find it useful, too.

      Cheers. Emanuel

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account