Summary: Learn how to use Windows PowerShell and conditional formatting to discover and format time spans.
Hey, Scripting Guy! What is a time span, and why would I want to use one? Just sayin'…
—JR
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.
- Understanding PowerShell and Basic String Formatting provided a great overview to the basics of using the Format method from the String class and the format operator from Windows PowerShell for composite formatting.
- Use PowerShell to Format Strings with Composite Formatting dove deeply into the use of composite formatting and using various format specifiers.
- Use PowerShell and Conditional Formatting to Format Numbers talked about using format specifiers to display percentages.
- Use PowerShell and Conditional Formatting to Format Dates discussed how to control the format of dates.
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.
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 Stringson MDSN.
An example of using the three standard TimeSpan format strings with composite formatting is shown in the image that follows.
Note For complete information about composite formatting, see Composite Formatting on MSDN.
Example 1: Use the static WriteLinemethod
To use standard TimeSpan format strings with the static WriteLinemethod 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 WriteLinemethod 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.
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