Date arithmetic with PowerShell
- select the contributor at the end of the page -
If you’ve written more than a few scripts, or done any kind of intermediate programming with dates, you know it can get complicated quickly. You’ll soon loathe having to figure out how many days are between the second Tuesday in April and the third Wednesday in May. Heaven help you if you have to calculate anything complicated with leap years. It’s a nightmare! Living up to its user-friendly name, PowerShell comes through in simplifying date arithmetic as much as possible. For example, I can get the weekday and date 89 days from now with this single intuitive line of code:
(Get-Date).AddDays(89). It’s a beautiful thing. The syntax is pretty obvious, right? I want to get today’s date and add 89 days to it. How about 93 days in the past? Just use
-93 as the parameter value for
AddDays()! If you’re new to PowerShell and using dates, I highly recommend checking out this Windows PowerShell Tip of the Week article on TechNet.
I love examples. A good example is worth a thousand words, so let’s go over one now. How often do you find yourself trying to figure out the date of an upcoming weekday? For example, someone tells you they’re going to meet you next Friday, but there’s no next Friday on a calendar. How convenient would it be to simply type:
Get-Weekday 'Next Friday' and immediately get the date? It’s the small things in life, you know?
Get-Weekday function has a single parameter
$Weekday. You can either type in a weekday and get the date for that upcoming day, or you can use the next or last operator followed by a weekday. Here’s how it was created:
One of the first lines you’ll see is a parameter validation line.
Because we know that our Weekday parameter must contain the name of a day of the week—and there are only seven of them—it’s a pretty good guess anything else would throw us an error. This ensures that only an actual day of the week is used.
Next, we drop into the process block of the function where we break out the regular expressions!
To give the user the most flexibility, I’m allowing case-insensitive matching of the weekday. I always convert the
$Weekday parameter value to lowercase to ensure a match is made whether a user types
sunday. Once converted, I can then use the very handy
[regex] type accelerator and the
Matches() method to perform a regex query on our
$Weekday parameter value and the weekday regex string. In doing so, I am now sure that the
$DesiredWeekDay variable won’t contain the string
last and will always be the weekday I want.
In the next block, I’m figuring out whether the user wants the next weekday or the last weekday.
I’m using an if/then construct here. This code snippet determines the number of days I’ll need to add to or subtract from today to get the correct date. You can see that if the user wants the next weekday—or doesn’t specify at all—I’m going to find the next 0 to 6 days. If the user wants the last weekday, I’ve simply inversed this range to the negative. The values in this
$Range will be used as the parameter value for our
AddDays() method, which you’ll see in a moment.
Finally, I’m enumerating each of the values inside of our
In this foreach loop, I’m using the values inside
$Range as the days to pass to the
AddDays() method. This will enable me to have a
[datetime] object where I can glean lots of useful information for that particular date—most importantly, the
DayOfWeek property. In this construct, I’m checking to see whether the value of
$Day.DayOfWeek matches the value of the weekday we’re looking for. If I find a match, then the function is outputting correctly and we’re done!
You are welcome to download this sample
Get-Weekday function. You can use it to expand upon what I’ve started here. I encourage you to improve upon it by adding the functionality you need—to get the last Tuesday of the month, or even 10 Thursdays from now! Use your imagination and add as much functionality as you want to create a universal, plain English-to-date translator script!