Converting date strings in PowerShell
The Get-Date cmdlet lets us create, convert, and format date strings to DateTime .NET objects. However, there’s one thing it cannot do, convert a date string which is not a format it expects (defines by your system locale). For example, if your current culture is en-US you can pass a date string in the format of MM/dd/yyyy to the –Date parameter and Get-date will convert it to a DateTime object:
PS > Get-Date -Date 4/13/2011
Wednesday, April 13, 2011 12:00:00 AM
On the other hand, if we pass a string in the format of dd/MM/yyyy it fails:
PS > Get-Date -Date 13/4/2011
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "13/4/2011" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
As you can see from the above error, Get-Date complains that "13/4/2011" was not in the correct format. A common case to this kind of date strings is when you have a third party application that writes date strings, not in the format of your locale, to log files. The only way to convert those strings to a valid DateTime object is to use the ParseExact static method of the DateTime .NET class. The ParseExact method is an overloaded member (we can invoke it in three ways, each with its own set of arguments). Instead of using the method directly I wrapped the first overload in an Advanced Function, ConvertFrom-DateString.
function ConvertFrom-DateString
{
[OutputType('System.DateTime')]
[CmdletBinding(DefaultParameterSetName='Culture')]
param(
[Parameter(
Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
HelpMessage='A string containing a date and time to convert.'
)]
[System.String]$Value,
[Parameter(
Mandatory=$true,
Position=1,
HelpMessage='The required format of the date string value'
)]
[Alias('format')]
[System.String]$FormatString,
[Parameter(ParameterSetName='Culture')]
[System.Globalization.CultureInfo]$Culture=$null,
[Parameter(Mandatory=$true,ParameterSetName='InvariantCulture')]
[switch]$InvariantCulture
)
process
{
if($PSCmdlet.ParameterSetName -eq 'InvariantCulture')
{
$Culture = [System.Globalization.CultureInfo]::InvariantCulture
}
Try
{
[System.DateTime]::ParseExact($Value,$FormatString,$Culture)
}
Catch [System.FormatException]
{
Write-Error "'$Value' is not in the correct format."
}
Catch
{
Write-Error $_
}
}
<#
.SYNOPSIS
Converts a string representation of a date.
.DESCRIPTION
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified format and culture-specific format
information. The format of the string representation must match the specified
format exactly.
.PARAMETER Value
A string containing a date and time to convert.
.PARAMETER FormatString
The required format of the date string value. If FormatString defines a
date with no time element, the resulting DateTime value has a time of
midnight (00:00:00).
If FormatString defines a time with no date element, the resulting DateTime
value has a date of DateTime.Now.Date.
If FormatString is a custom format pattern that does not include date or
time separators (such as "yyyyMMdd HHmm"), use the invariant culture
(e.g [System.Globalization.CultureInfo]::InvariantCulture), for the provider
parameter and the widest form of each custom format specifier.
For example, if you want to specify hours in the format pattern, specify
the wider form, "HH", instead of the narrower form, "H".
The format parameter is a string that contains either a single standard
format specifier, or one or more custom format specifiers that define the
required format of StringFormats. For details about valid formatting codes,
see 'Standard Date and Time Format Strings' (http://msdn.microsoft.com/en-us/library/az4se3k1.aspx)
or 'Custom Date and Time Format Strings' (http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx).
.PARAMETER Culture
An object that supplies culture-specific formatting information about the
date string value. The default value is null. A value of null corresponds
to the current culture.
.PARAMETER InvariantCulture
Gets the CultureInfo that is culture-independent (invariant). The invariant
culture is culture-insensitive. It is associated with the English language
but not with any country/region.
.EXAMPLE
ConvertFrom-DateString -Value 'Sun 15 Jun 2008 8:30 AM -06:00' -FormatString 'ddd dd MMM yyyy h:mm tt zzz' -InvariantCulture
Sunday, June 15, 2008 5:30:00 PM
This example converts the date string, 'Sun 15 Jun 2008 8:30 AM -06:00',
according to the specifier that defines the required format.
The InvariantCulture switch parameter formats the date string in a
culture-independent manner.
.EXAMPLE
'jeudi 10 avril 2008 06:30' | ConvertFrom-DateString -FormatString 'dddd dd MMMM yyyy HH:mm' -Culture fr-FR
Thursday, April 10, 2008 6:30:00 AM
In this example a date string, in French format (culture). The date string
is piped to ConvertFrom-DateString. The input value is bound to the Value
parameter. The FormatString value defines the required format of the date
string value. The result is a DateTime object that is equivalent to the date
and time contained in the Value parameter, as specified by FormatString and
Culture parameters.
.EXAMPLE
ConvertFrom-DateString -Value 'Sun 15 Jun 2008 8:30 AM -06:00' -FormatString 'ddd dd MMM yyyy h:mm tt zzz'
Sunday, June 15, 2008 5:30:00 PM
Converts the date string specified in the Value parameter with the
custom specifier specified in the FormatString parameter. The result
DateTime object format corresponds to the current culture.
.INPUTS
System.String
You can pipe a string that contains a date and time to convert.
.OUTPUTS
System.DateTime
.NOTES
Author: Shay Levy
Blog : http://PowerShay.com
.LINK
http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx
#>
}
ConvertFrom-DateString is decorated with Comment Based Help so you can use the Get-Help cmdlet to get help for its parameters as well as code examples. Let’s see how we can use the function to convert a date string to a DateTime object.
PS> 'Tue Mar 29 14:49:04 2011' | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'
Tuesday, March 29, 2011 2:49:04 PM
The Value parameter accept pipeline input so we can pipe the string to the function. We also specify the format of the string, specifying each element position in the Format-String parameter. We didn’t specify the Culture parameter so the result is a DateTime object in the current culture of the local system. To get more help on .NET format specifiers, see "DateTimeFormatInfo Class" in the MSDN (Microsoft Developer Network) library at http://go.microsoft.com/fwlink/?LinkId=143638
Here’s another example with a French date string. This time we specify the string in the Value parameter and we also use the Culture parameter to tell the function that the string is in the fr-FR culture:
PS > ConvertFrom-DateString –Value 'jeudi 10 avril 2008 06:30' -FormatString 'dddd dd MMMM yyyy HH:mm' -Culture fr-FR
Thursday, April 10, 2008 6:30:00 AM
The function can also be downloaded from the TechNet Script Center Repository.
Enjoy!