Use PowerShell to Work with Individual Dates


Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to work with dates.

Microsoft Scripting Guy, Ed Wilson, is here. I don’t know about you, but one thing about my life as the Scripting Guy is that it keeps me busy. “Keeping busy” is a slang expression that means, “Dude, you are swamped.”

The Scripting Wife and I just spent most of last week planning events for the remainder of 2015. Yep, my year is pretty well planned out. Not because I love being super organized. In fact, my default behavior is rather the opposite—I prefer a more natural, organic schedule. But the only way I can get to everything is if I have a plan.

This means that I spend a lot of time with dates and calendars. Actually, the Scripting Wife is the one who keeps up with that stuff because she really is organized. In fact, I have seen more than one tweet or Facebook post that said something to the effect that if you want me to do something, you better organize it with the Scripting Wife. She is great. Anyway…

One of the really cool things about Windows PowerShell is that it makes it easy for me to see what day the week a specific date will occur. It also makes it pretty easy for me to see how many days remain until a specific date occurs. There are several ways I can create dates.

Yesterday I talked a little bit about System.DateTime objects. If I create a specific date, instead of just returning today’s date, I am creating a DateTime object that represents a date in the future or the past. One way to create a specific date is to use the Get-Date cmdlet and then specify values for the –Day, –Month, and –Year parameters. For example, you may know that William Shakespeare died on April 23, 1616. However, most people do not know that that was a Saturday. Here is how I found out that bit of trivia:

PS C:> Get-Date -Month 4 -Day 23 -Year 1616

Saturday, April 23, 1616 2:20:19 PM

When I use Get-Date in this way, it returns a DateTime object (of course), but it is interesting that because I did not specify a time portion of the DateTime object, it uses my local system time. So, I ran the command above at 2:20:19 PM.

The Get-Date cmdlet will also accept a DateTime object as input. I found this out by looking at the syntax of the command. When I use Get-Help to look at the syntax, I see that the –Date parameter accepts <DateTime> for input. This tells me that the input value is expected to be an instance of the System.DateTime object. This is shown here:

PS C:> (Get-Help get-date).syntax

Get-Date [[-Date] <DateTime>] [-Day <Int32>] [-DisplayHint <DisplayHintType>] [-Format <String>] [-Hour

<Int32>] [-Millisecond <Int32>] [-Minute <Int32>] [-Month <Int32>] [-Second <Int32>] [-Year <Int32>]

[<CommonParameters>]

Get-Date [[-Date] <DateTime>] [-Day <Int32>] [-DisplayHint <DisplayHintType>] [-Hour <Int32>]

[-Millisecond <Int32>] [-Minute <Int32>] [-Month <Int32>] [-Second <Int32>] [-UFormat <String>] [-Year

<Int32>] [<CommonParameters>]

Because Windows PowerShell expects a DateTime object for input to the –Date parameter, it will be happy with anything that I supply to the parameter that it can convert into an instance of a DateTime object. This is because Windows PowerShell does automatic type conversion. So anything that is reasonably formatted will be converted.

To manually convert a string that represents a date into a DateTime object, I can use the type accelerator, [DateTime], and it will convert (cast) the string to the object. Here is an example:

PS C:> [datetime]”June 15, 1215″

Monday, June 15, 1215 12:00:00 AM

To prove that I actually converted the string to an instance of the System.DateTime object, I can pipe the results into the Get-Member cmdlet, for example:

[datetime]”June 15, 1215″ | Get-Member 

I can also use the GetType method directly from the expression. This technique is shown here:

PS C:> ([datetime]”June 15, 1215″).GetType()

IsPublic IsSerial Name                            BaseType                                       

——– ——– —-                                     ——–                                       

True     True     DateTime                    System.ValueType                               

So, because I can convert a string to a DateTime object, and because the Get-Date cmdlet accepts a DateTime object as input, I have seen people do something like the following:

Get-date -date ([datetime]”June 15, 1215″)

This works, but dude, it is a lot of extra work. In fact, it does not do any more than the previous expression. So how does Get-Date “June 15, 1215” actually work?

Well, the default parameter of Get-Date is actually –Date. And as I said earlier, it expects a DateTime object, and therefore it will try to convert whatever I give it into a DateTime object. I can see that –Date is the default parameter by using the Get-Help cmdlet. This is shown here:

PS C:> Get-Help get-date -Parameter date

-Date <DateTime>

    Specifies a date and time. By default, Get-Date gets the current system date and time.

    Type the date in a format that is standard for the system locale, such as dd-MM-yyyy (German

    [Germany]) or MM/dd/yyyy (English [United States]).

    Required?                    false

    Position?                    1

    Default value                Current date

    Accept pipeline input?       True (ByValue, ByPropertyName)

    Accept wildcard characters?  false

Windows PowerShell is pretty good when it comes to converting my input date value. Here are some examples that it translates into a DateTime object:

PS C:> get-date 6-15-1215

Monday, June 15, 1215 12:00:00 AM

PS C:> get-date 6/15/1215

Monday, June 15, 1215 12:00:00 AM

PS C:> get-date 6.15.1215

Monday, June 15, 1215 12:00:00 AM

It will even accept abbreviations. Here is an example of using an abbreviation:

PS C:> get-date “Jun. 15, 1215”

Monday, June 15, 1215 12:00:00 AM

But if I do not use quotation marks, I get an error message. This is shown here:

PS C:> get-date Jun. 15, 1215

Get-Date : Cannot bind parameter ‘Date’. Cannot convert value “Jun.” to type “System.DateTime”. Error:

“String was not recognized as a valid DateTime.”

At line:1 char:10

+ get-date Jun. 15, 1215

+          ~~~~

    + CategoryInfo          : InvalidArgument: (:) [Get-Date], ParameterBindingException

    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand

In addition, if I use the wrong symbol for a separator it generates an error message:

PS C:> get-date 6151215

Get-Date : Cannot bind parameter ‘Date’. Cannot convert value “6151215” to type “System.DateTime”.

Error: “String was not recognized as a valid DateTime.”

At line:1 char:10

+ get-date 6151215

+          ~~~~~~~~~

    + CategoryInfo          : InvalidArgument: (:) [Get-Date], ParameterBindingException

    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand

Here is some fun trivia. If I do not remember how many days are in a month (such as February), I can wing it. So February 31, 2015 actually becomes March 3 (that is three days after the end of February, which is February 28. Here is what I am talking about:

PS C:> get-date -Day 31 -Month 2 -Year 2015

Tuesday, March 3, 2015 3:24:06 PM

I thought, “Wow, that is pretty cool. I wonder if I can, say, add 30 days to February 15, and come up with something like March the 17?” So I tried it:

PS C:> get-date -Day 45 -Month 2 -Year 2015

Get-Date : Cannot validate argument on parameter ‘Day’. The 45 argument is greater than the maximum

allowed range of 31. Supply an argument that is less than or equal to 31 and then try the command again.

At line:1 char:15

+ get-date -Day 45 -Month 2 -Year 2015

+               ~~

    + CategoryInfo          : InvalidData: (:) [Get-Date], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetDateCommand

Nope. The error message tells me that the maximum value of -Day is 31, which makes sense, I guess.

That is all there is to working with dates in Windows PowerShell. Date Time Week will continue tomorrow when I will talk about adding and subtracting days.

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 

Comments (1)

  1. BPK says:

    Hi Ed. I have a question from a challenge with [DateTime] accelerator. How is is that even though my Culture & UICulture is en-US but with the DateTimeFormat property customized to dd-MM-yyyy Get-Date -Date "23/1/2015" works perfectly but [DateTime]"23/1/2015"
    throws a conversion error?

Skip to main content