January 22nd, 2015

Formatting Date Strings with PowerShell

Doctor Scripto
Scripter

Summary: Microsoft Scripting Guy, Ed Wilson, talks about formatting date strings with Windows PowerShell. Microsoft Scripting Guy, Ed Wilson, is here. It seems that different ways to display dates and times are in great supply. In fact, there are dozens of ways to do this. If I decide that I do not like the way a date or time displays, I can change it. In addition, the way a particular date style displays in one country is different than the way it displays in another country. These differences are part of the culture settings. For example, the output from the Get-Date cmdlet appears differently depending on the UI culture settings. Here is an example:

PS C:> Use-Culture de-de {get-date}

Mittwoch, 21. Januar 2015 12:23:40

PS C:> Get-Date

Wednesday, January 21, 2015 12:23:45 PM    Note  The Use-Culture function is not standard in Windows PowerShell or Windows. It comes from Lee Holmes’  
   PowerShell Cookbook module. I installed it from the PowerShell Gallery, but it is also available on PoshCode. In general, I want the date to automatically change the way it displays based on culture settings because it helps avoid confusion. There may be times when I want to override this behavior. I can do this by directly formatting the date. I can use the ToString method and specify the display pattern. The pattern MM – dd –yyyy specifies that I want the month, day, and year to appear in that order. The MM is case sensitive. Here is an example:

PS C:> (Get-Date -Month 2 -Day 12 -Year 2015).tostring(“MM-dd-yyyy”)

02-12-2015 There can be a very real problem with this technique. In many regions, the day value comes first. So is the month February or is it December? Here is how the date displays when I use German UI culture settings:

PS C:> Use-Culture de-DE {(Get-Date -Month 2 -Day 12 -Year 2015).tostring(“MM-dd-yyyy”)}

02-12-2015 According to their pattern, this is December 2, 2015. Here is the short date pattern:

PS C:> [System.Globalization.CultureInfo]::GetCultureInfo(1031).DateTimeFormat.ShortDatePattern

dd.MM.yyyy Now the culture settings use a hexadecimal value from the National Language Support API. Germany uses a hex value of 0x0407. If I convert it to a decimal format, it becomes 1031. This is shown here:

PS C:> 0x0407

1031 I double check that I have the correct language settings by using the GetCulturalInfo static method:

PS C:> [System.Globalization.CultureInfo]::GetCultureInfo(1031)

LCID             Name             DisplayName                                                    

—-                 —-                  ———–                                                     

1031             de-DE            German (Germany)       So if I really want to display a short date, I need to use a format specifier to tell Windows PowerShell to display a short date. In this way, it will be culture specific. On the MSDN page, Standard Date and Time Format Strings, I learn that the .NET short date specifier is “d”. So, I use the –format parameter of Get-Date, and the following appears:

PS C:> get-date -Format d

1/21/2015 But what about using a different culture? Well, this is how it displays in culture de-DE:

PS C:> Use-Culture de-DE {get-date -Format d}

21.01.2015 As a best practice, I should avoid creating my own date format strings if at all possible. If I use the built-in .NET date format specifiers, Windows PowerShell automatic displays it in the correct format. Here is a table of the .NET date format specifiers.

Format Specifier

Description

Examples

d

Short date pattern

2009-06-15T13:45:30 -> 6/15/2009 en-US

2009-06-15T13:45:30 -> 15/06/2009 fr-FR

2009-06-15T13:45:30 -> 2009/06/15 ja-JP

D

Long date pattern

2009-06-15T13:45:30 -> Monday, June 15, 2009 en-US

2009-06-15T13:45:30 -> 15 июня 2009 г. ru-RU

2009-06-15T13:45:30 -> Montag, 15. Juni 2009 de-DE

f

Full date pattern with short time pattern

2009-06-15T13:45:30 -> Monday, June 15, 2009 1:45 PM en-US

2009-06-15T13:45:30 -> den 15 juni 2009 13:45 sv-SE

2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 1:45 μμ el-GR

F

Full date pattern with long time pattern

2009-06-15T13:45:30 -> Monday, June 15, 2009 1:45:30 PM en-US

2009-06-15T13:45:30 -> den 15 juni 2009 13:45:30 sv-SE

2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 1:45:30 μμ el-GR

g

General date pattern with short time pattern

2009-06-15T13:45:30 -> 6/15/2009 1:45 PM en-US

2009-06-15T13:45:30 -> 15/06/2009 13:45 es-ES

2009-06-15T13:45:30 -> 2009/6/15 13:45 zh-CN

G

General date pattern with long time pattern

 2009-06-15T13:45:30 -> 6/15/2009 1:45:30 PM en-US

2009-06-15T13:45:30 -> 15/06/2009 13:45:30 es-ES

2009-06-15T13:45:30 -> 2009/6/15 13:45:30 zh-CN

M, m

Month/day pattern

2009-06-15T13:45:30 -> June 15 en-US

2009-06-15T13:45:30 -> 15. juni da-DK

2009-06-15T13:45:30 -> 15 Juni id-ID

O, o

Round-trip date/time pattern

2009-06-15T13:45:30  –> 2009-06-15T13:45:30.0000000-07:00

2009-06-15T13:45:30 –> 2009-06-15T13:45:30.0000000Z

2009-06-15T13:45:30 2009-06-15T13:45:30.0000000

2009-06-15T13:45:30-07:00 –> 2009-06-15T13:45:30.0000000-07:00

R, r

RFC1123 pattern

2009-06-15T13:45:30 -> Mon, 15 Jun 2009 20:45:30 GMT

s

Sortable date/time pattern

2009-06-15T13:45:30 -> 2009-06-15T13:45:30

2009-06-15T13:45:30 -> 2009-06-15T13:45:30

t

Short time pattern

2009-06-15T13:45:30 -> 1:45 PM en-US

2009-06-15T13:45:30 -> 13:45 hr-HR

2009-06-15T13:45:30 -> 01:45 ar-EG

T

Long time pattern

2009-06-15T13:45:30 -> 1:45:30 PM en-US

2009-06-15T13:45:30 -> 13:45:30 hr-HR

2009-06-15T13:45:30 -> 01:45:30 م ar-EG

u

Universal sortable date/time pattern

2009-06-15T13:45:30 -> 2009-06-15 20:45:30Z

U

Universal full date/time pattern

2009-06-15T13:45:30 -> Monday, June 15, 2009 8:45:30 PM en-US

2009-06-15T13:45:30 -> den 15 juni 2009 20:45:30 sv-SE

2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 8:45:30 μμ el-GR

Y, y

Year month pattern

2009-06-15T13:45:30 -> June, 2009 en-US

2009-06-15T13:45:30 -> juni 2009 da-DK

2009-06-15T13:45:30 -> Juni 2009 id-ID

That is all there is to using .NET date format specifiers. Date Time Week will continue tomorrow when I will talk about more cool stuff. 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

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

2 comments

Discussion is closed. Login to edit/delete existing comments.

  • Søren B. Simonsen

    Can you explain why Get-Date -Format U is having a Z at the end? Normally Z represents Zulu equal to UTC+0. If I run:
    Get-Date
    Get-Date -Format u
    Get-Date -Format U
    I get:
    31. marts 2020 12:11:16
    2020-03-31 12:11:16Z
    31. marts 2020 10:11:16
    First is local time and month in Danish.
    Next is also local time but in a very nice sortable format and having Z in the end
    Last is my local time converted...

    Read more
  • Pramod Yadav

    And finally, the “proper way” to format dates. Thank you doctor Scripto!
    Your posts have helped enormously building our test framework in PowerShell.

    P.S: The use-culture module seems to be unavailable on the links in the post (or when searched in PowerShell gallery). Thought of bringing this to your notice. Post is still super useful, considering all the options available in format options.