9

#PSTip How to check if a DateTime string is in a specific pattern

You want to be able to check and allow only date and time strings that are in a specific date time format pattern. For example, you get a string and want to check if it is in a sortable date and time pattern.

Let’s find first how a sortable date and time string looks like. Note that format string is culture dependent:

PS> (Get-Culture).DateTimeFormat.SortableDateTimePattern
yyyy'-'MM'-'dd'T'HH':'mm':'ss

Instead of using, or having to remember that long pattern, the .NET Framework offers us a composite format string
that is an equivalent of the above, kind of a shortcut pattern, the “s” standard format string. We can format a date and time object to a sortable pattern with the Get-Date cmdlet.

PS> Get-Date -Format s
2013-07-05T11:45:10

Now, given a date and time string, how you check it complies to a specific pattern?

The DateTime .NET structure has a static method we can use to parse strings and return DateTime objects, the ParseExact method. It converts the specified string representation of a date and time to its DateTime equivalent. If the format of the string does not match a specified format exactly an exception is thrown.

The method accepts three arguments:

  1.  s – A string that contains a date and time to convert.
  2. format – A format specifier that defines the required format of ‘s’.
  3. provider – An object that supplies culture-specific format information about ‘s’.

Wrapping it all into a function so we can reuse it any time we need to.

function Test-DateTimePattern
{
    param(
        [string]$String,
        [string]$Pattern,
        [System.Globalization.CultureInfo]$Culture = (Get-Culture),
        [switch]$PassThru
    )

    $result = try{ [DateTime]::ParseExact($String,$Pattern,$Culture) } catch{}

    if($PassThru -and $result)
    {
        $result
    }
    else
    {
        [bool]$result
    }

}

The function returns True/False if a given string is in the correct format. Add the PassThru switch to get back the parsed date and time object if the pattern was successfully parsed.

PS> Test-DateTimePattern -String '12:15 PM' -Pattern t
True

# invalid pattern, missing the AM/PM designator (try Get-Date -f g)
PS> Test-DateTimePattern -String '7/5/2013 12:16' -Pattern g
False

PS> Test-DateTimePattern -String '2013-07-05T11:45:12' -Pattern s -PassThru
Friday, July 5, 2013 11:45:12 AM

# invalid pattern, pattern should be in dd/MM/yyyy
PS> Test-DateTimePattern -String '12/14/2013' -Pattern d -Culture he-IL
False
Filed in: Columns, Tips and Tricks Tags: , ,

One Pingback/Trackback

  • Peter Kriegel

    In my point of view, the -PassThru parameter is not a common PowerShell Parameter. It should used as an very seldom exception. With that, your Function returns 2 kind of Objects this is perhaps unexpected! I think a better way is to return an Object which means $True and return $Null which means $False. $Null works seamless in the Pipeline!

    • PowerShellMag

      Thanks for the feedback Peter.

      I disagree with your statment that the PassThru parameter should be used very seldom and that the use of it is a bad practice. Generally speaking, any cmdlet that doesn’t return a result should have PassThru support imo, so we could leverage it and write the object in question back to the pipeline so it can be consumed by down stream commands (it doesn’t make sense to output a deleted object but thats arguable too). That said, I agree that my function is may not the usuaul way to use it but only beacuse it is a Test cmdlet.

      With regard to the output type objects, I don’t see any problem with returning multiple objects type. Take a look at Get-ChildItem for example, it returns FileInfo or FolderInfo objects. Test-Connection can output a Boolean in case the There are many cmdlets

      As for Test cmdlets, they should return True/False and not null values.

      • Peter Kriegel

        You are right!

        In case of the Out-GridView and other Cmdlets I saw the PassThru parameter as a parameter to fix Cmdlets without output. This was the wrong conclusion.

        In the mean time I wrote even some Test-xxx Cmdlets and the PassThru parameter comes very handy for those kind of Cmdlet.

        But I sta with the statement. A normal Cmdlet or Function should not use the PassThru parameter it naturally should output a Object.

  • Greg Wojan

    Shay,
    On my Windows 7/PowerShell 3 system your first example returns ‘false’ and the second returns ‘true’.

    • PowerShellMag

      Hi Greg

      The function is using yiour culture settings to parse the pattern.
      My tests were under the en-US culture, do you get the same results when you set the Culture parameter to en-US?

      • Greg Wojan

        I think I’m losing my mind. ;-) The second example is correct — don’t know how I buggered that one.

        The first example returns false even with the ‘en-US’ culture setting. If I remove the ‘PM’ the test returns true.

        PS C:Userswojang> Test-DateTimePattern -String ’12:15 PM’ -Pattern t
        False
        PS C:Userswojang> Test-DateTimePattern -String ’12:15 PM’ -Pattern t -Culture en-US
        False

        PS C:Userswojang> Test-DateTimePattern -String ’07/05/2013 12:16′ -Pattern g
        True
        PS C:Userswojang> Get-Date -f t
        09:02

        Note the output of Get-Date -f t…

        • PowerShellMag

          PS> Test-DateTimePattern -String ’12:15 PM’ -Pattern t -Culture en-US

          $true

          Do you get another result? Another way to check the pattern would be to assign the values directly to the underklying method and check the error you get back.

          [DateTime]::ParseExact($String,$Pattern,$Culture)

          • Greg Wojan

            Problem solved…
            When in doubt *REALLY* RTFM. The ‘t’ pattern uses the settings for ‘Short Date’ format in international settings which I always set to ‘HH:MM’.

            Just another case of the computer actually doing what I told it to do.

            Thanks for putting up with me. ;-)

  • Pingback: Microsoft Most Valuable Professional (MVP) – Best Posts of the Week around Windows Server, Exchange, SystemCenter and more – #37 - Dell TechCenter - TechCenter - Dell Community

© 2014 PowerShell Magazine. All rights reserved. XHTML / CSS Valid.
Proudly designed by Theme Junkie.
%d bloggers like this: