Summary: Learn how to use Windows PowerShell and conditional formatting to discover and  format time spans.

Hey, Scripting Guy! Question Hey, Scripting Guy! What is a time span, and why would I want to use one? Just sayin'…

—JR

Hey, Scripting Guy! Answer Hello JR,

Microsoft Scripting Guy, Ed Wilson, is here. This morning is one of those mornings that remind me of when I was growing up in Florida. The sky is overcast, and a ground fog clothes the lawn. The air is cool, but heavy with humidity. I am positive I hear sea gull calls pierce the thick silence, yet I have not seen a sea gull in months. Maybe I am not certain that I am in Charlotte, North Carolina after all. I am sipping a cup of Darjeeling tea with cinnamon stick, lemon grass, peppermint, spearmint, licorice root, and juniper berries, and munching on a freshly baked strawberry scone while I check my scripter@microsoft.com email.

JR, a time span measures the amount of time that is elapsing from one point in time to another point in time. Therefore, when figuring out the amount of time between March 14, 2013 and March 12, 2013, a TimeSpan object returns as shown here.

PS C:\> [datetime]"3/14/13" -[datetime]"3/12/13"

 

Days              : 2

Hours             : 0

Minutes           : 0

Seconds           : 0

Milliseconds      : 0

Ticks             : 1728000000000

TotalDays         : 2

TotalHours        : 48

TotalMinutes      : 2880

TotalSeconds      : 172800

TotalMilliseconds : 172800000

Note   This is the last blog post in a series of five that talk about using format methods and operators in Windows PowerShell.

The problem with the default display of a TimeSpan object

By default, Windows PowerShell displays all of the properties associated with a TimeSpan object. As seen in the previous script, the output can be a bit cluttered. This is OK if I am working interactively from within the Windows PowerShell console and I only want to see something like the amount of time that has lapsed between two dates.

I can see the different properties when I send the TimeSpan object to the Get-Member cmdlet. This technique is shown here.

[datetime]"3/14/13" -[datetime]"3/12/13" | Get-Member -MemberType *property

The command and the output associated with the command are shown in the following image.

Image of command output

So, if I only want to know the number of hours between two date/time objects, I need to first find out the property name (by using Get-Member or by simply running the command and examining the output). Then I can use the group and dot method to retrieve the specific property. This is shown here.

PS C:\> ([datetime]"3/14/13" -[datetime]"3/12/13").totalhours

48

In general, I use this technique when I am interested in a specific property from a TimeSpan object. But there is a better (and much more flexible) way to obtain exactly what I want from a TimeSpan object.

Use composite formatting and standard TimeSpan format strings

The easiest way to use the standard TimeSpan format strings is to combine them with composite formatting. When I do this, it provides three formats. The formats are shown in the following table.

Format Specifier

Name

  “c”

  Constant format (not culture sensitive.

  [-]d.hh:mm:ss.[fffffff]

  “g”

  General short format (culture sensitive)

  [-]d.hh:mm:ss.[fffffff]

  “G”

  General long format (culture sensitive)

  [-]d.:hh:mm:ss.fffffff

Note   For complete documentation about these specifiers, see Standard TimeSpan Format Strings on MDSN.

An example of using the three standard TimeSpan format strings with composite formatting is shown in the image that follows.

Image of command output

Note   For complete information about composite formatting, see Composite Formatting on MSDN.

Example 1: Use the static WriteLine method

To use standard TimeSpan format strings with the static WriteLine method from the system.console .NET Framework class, I use a string to identify the value I display, and then I use a format item with the “c” format specifier. The “c” format specifier is a constant value that is not cultural sensitive. Therefore, the values always appear in the same order. The second parameter that the WriteLine method accepts is a TimeSpan object. The script and its associated output are shown here.

PS C:\> $ts = [datetime]"3/14/13" -[datetime]"3/12/13"

PS C:\> [console]::WriteLine("The lapsed time is: {0:c}", $ts)

The lapsed time is: 2.00:00:00

Example 2: Use the Windows PowerShell format operator

To use standard TimeSpan format strings with the Windows PowerShell format operator, I add a string descriptor, and then use my format item to specify the substitution object and the format to use on the left side of the format operator. On the right side of the format operator, I specify the variable holding the TimeSpan object. The script is shown here.

PS C:\> $ts = [datetime]"3/14/13" -[datetime]"3/12/13"

PS C:\> "The lapsed time is: {0:g}" -f $ts

The lapsed time is: 2:0:00:00

Example 3: Time span with milliseconds

One of the things that is useful with the “c” and the “g” standard TimeSpan format strings is that they display the portion of the TimeSpan object that is required. Therefore, if a time span does not span days, it omits the days portion. If a TimeSpan object populates milliseconds, it adds that portion of the object.

In the script that follows, I store the current DateTime object. I wait for a while, and then I store a second DateTime object. Now I create a TimeSpan object representing the difference between the two TimeSpan objects. Lastly, I use the Windows PowerShell format operator to display a culture sensitive short time span. Because both times occurred on the same day, the day portion of the object does not display.

PS C:\> $now = get-date

PS C:\> $later = get-date

PS C:\> $nts = New-TimeSpan -Start $now -End $later

PS C:\> "The timespan is {0:g}" -f $nts

The time span is 0:09:03.1051821

This technique is shown here, and it illustrates the difference between the three standard time span format strings.

Image of command output

JR, that is all there is to using a time span. Join me tomorrow for the Weekend Scripter when I will talk about using a custom time span format specifier.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy