Learn about Windows PowerShell
Hey, Scripting Guy! I need to use Windows PowerShell to be able to parse dates. We have dates that are displayed in different ways. Some are day/month/year, others are month/day/year, and still others are year/month/day. I need to be able to express these different date configurations with a minimal amount of monkeying around. Is this doable using Windows PowerShell?
Microsoft Scripting Guy Ed Wilson here. My significant other was all excited about listening to the PowerScripting Podcast the other night, not because I was on it, but because one of our good friends from Sapien Software was on it. We have known Alex Riedel since I wrote my first scripting book for Microsoft Press. He is a really cool and intelligent person. I met him in real life for the first time last year at Tech·Ed 2009 in LA (back before I had my ear problems). The following photo shows me and some imaginary friends hanging out at Tech·Ed 2009.
AH, you do not really need to parse dates in order to display the date information in a particular manner. I have seen scripts where people stored the datetime object that was returned by the Get-Date cmdlet, and then they retrieved the day, month, and year properties from the object and stored those values in variables. After they had that, they manually built up the date as shown here:
PS C:\> $date = Get-Date PS C:\> $d = $date.day PS C:\> $m = $date.month PS C:\> $y = $date.year PS C:\> "$d/$m/$y" 29/7/2010 PS C:\> "$m/$d/$y" 7/29/2010 PS C:\> "$y/$m/$d" 2010/7/29 PS C:\>
While there is nothing wrong with such an approach, it is a lot of extra work that does not really add any value to the script at all. A better approach is to use one of the formatting specifiers. The Get-Date cmdlet will accept two types of format specifiers. One is the .NET format strings and the other is UNIX formatting strings. The UNIX formatting strings are perhaps the easiest to understand, at least for basic functionality. To get the day you use %d. For the month you use %m, and for the two-digit year, you use %y. This is shown here:
PS C:\> Get-Date -UFormat %d 29 PS C:\> Get-Date -UFormat %m 07 PS C:\> Get-Date -UFormat %y 10 PS C:\>
You can combine the UNIX formatting strings simply by appending one to the other. This is shown here:
PS C:\> Get-Date -UFormat %d%m%y 290710 PS C:\>
If you need a separator between the day/month/year, you simply add it at the appropriate location. You are not limited to a forward slash or a dash; you can use many different separators including the dollar sign, which elsewhere is a special character in Windows PowerShell. This is shown here:
PS C:\> Get-Date -UFormat %d/%m/%y 29/07/10 PS C:\> Get-Date -UFormat %d-%m-%y 29-07-10 PS C:\> Get-Date -UFormat %d.%m.%y 29.07.10 PS C:\> Get-Date -UFormat %d*%m*%y 29*07*10 PS C:\> Get-Date -UFormat %d$%m$%y 29$07$10 PS C:\>
At times, if you want the date in the standard mm/dd/yy format that is often used in the United States, you have two options. You can build it up using %m/%d/%y, or you can use the special %D format string. These two options are illustrated here:
PS C:\> Get-Date -UFormat %m/%d/%y 07/29/10 PS C:\> Get-Date -UFormat %D 07/29/10 PS C:\>
If you would like the date display to change based upon the culture input of the computer, you can use %x.
If you want the day, month, four-digit year, and the time, use the %c option:
PS C:\> Get-Date -UFormat %c Thu Jul 29 17:04:10 2010 PS C:\>
Up to this point, all our format strings have been placed after the –UFormat parameter without any quotation marks required. This is because the parameter expects a string to be supplied as a value, and therefore it treats it accordingly. However, if you want to display the full month name, the day of the week, and four-digit year, which would require some spaces, the following syntax generates an error:
PS C:\> Get-Date -UFormat %B %d, %Y Get-Date : Cannot convert 'System.Object' to the type 'System.DateTime' required by parameter 'Da te'. Specified method is not supported. At line:1 char:9 + Get-Date <<<< -UFormat %B %d, %Y + CategoryInfo : InvalidArgument: (:) [Get-Date], ParameterBindingException + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.GetDateCommand PS C:\>
The solution is to place the string to be supplied to the –UFormat parameter inside quotation marks. This is shown here:
PS C:\> Get-Date -UFormat "%B %d, %Y" July 29, 2010 PS C:\>
The syntax for the UNIX format strings for dates is documented in the online help. Use Get-Help Get-Date –Full to see the documentation. The other way of formatting the date is to use the .NET Framework DateTime format strings. There are two kinds of DateTime format strings available via the .NET Framework. The first kind is the standard DateTime format strings, and the second kind is the Custom DateTime format strings. For example, if you need to display a short date pattern, you use the lowercase d in the cultural specific form of mm/dd/yy. This is shown here:
PS C:\> Get-Date -Format d 7/29/2010 PS C:\>
By using the standard DateTime format strings, you can produce the long date pattern (D), the full date with a short time pattern (f), or even a full date with a long time pattern (F). These patterns are shown here:
PS C:\> Get-Date -Format D Friday, July 30, 2010 PS C:\> Get-Date -Format f Friday, July 30, 2010 11:32 AM PS C:\> Get-Date -Format F Friday, July 30, 2010 11:32:18 AM PS C:\>
You can create sortable date/time patterns that conform to ISO 8601 (s) or a universal sortable date/time pattern with no time zone conversion (u) or a universal sortable date/time pattern that displays universal time (U). These are shown here:
PS C:\> Get-Date -Format s 2010-07-30T11:36:23 PS C:\> Get-Date -Format u 2010-07-30 11:36:26Z PS C:\> Get-Date -Format U Friday, July 30, 2010 3:36:31 PM PS C:\>
If you need to define a custom date you use a combination of d, M and y. Note that the capital Y is not used. This can actually be a bit confusing if you are using the pattern ddMMMY. One other thing to keep in mind is that lowercase m is used with minutes, and capital M is used for months. If you are not careful, this can create a difficult troubleshooting scenario especially if you are writing code before 12 minutes after the hour. Examples of using these are shown here:
PS C:\> Get-Date -Format d 7/30/2010 PS C:\> Get-Date -Format dd 30 PS C:\> Get-Date -Format ddM 307 PS C:\> Get-Date -Format ddMM 3007 PS C:\> Get-Date -Format ddMMM 30Jul PS C:\> Get-Date -Format ddMMMY 30JulY PS C:\> Get-Date -Format ddMMMYY 30JulYY PS C:\> Get-Date -Format ddMMMy 30Jul10 PS C:\> Get-Date -Format ddMMMyy 30Jul10 PS C:\> Get-Date -Format ddMMMyyy 30Jul2010 PS C:\> Get-Date -Format ddMMMyyyy 30Jul2010 PS C:\>
AH, that is all there is to using Windows PowerShell to perform date manipulation. Date Week will continue tomorrow as we discuss subtracting dates.
We invite you to follow us on Twitter or Facebook. If you have any questions, send email to us at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson and Craig Liebendorfer, Scripting Guys
For the .NET formatiing, it's also helpful to know that using double quotes allows for similar formatting to the Unix variety you showed. For example:
PS C:\> Get-Date -Format "d MMMM, yyy"
3 August, 2010
PS C:\Users\W> Get-Date -Format "yyy/MM/dd"
PS C:\Users\W> Get-Date -Format "'Day' dd '%' 'Month' MM '$' 'Year' yy"
Day 03 % Month 08 $ Year 10