Windows PowerShell Tip of the Week

Here’s a quick tip on working with Windows PowerShell. These are published every week for as long as we can come up with new tips. If you have a tip you’d like us to share or a question about how to do something, let us know.

Find more tips in the Windows PowerShell Tip of the Week archive.

More Fun with Dates (and Times)

What’s that? Do we know anything about the Windows PowerShell cmdlet Get-Date? Heck, yes; after all, everyone knows about the Get-Date cmdlet. Besides, what is there to know; the Get-Date cmdlet enables you to get a date-time value. Need to get the current date and time? Then just do this:

$a = Get-Date

Which, in turn, makes $a equal to this (or something very much like it):

Thursday, October 25, 2007 1:50:4 PM

Now the variable $a is a date-time object containing the current date and time. Want to get a date object equal to a different date and time? Sure, why not:

$a = Get-Date "5/1/2006 7:00 AM"

That’s all there is to it, right?

Um, we said, “Right?”

Wrong.

Accessing Other Date Properties Using Get-Date

As it turns out, there are some other cool things you can do with Get-Date. Like what? Well, take a look at the following script, one that teases out the individual parts of a date-time value:

$a = Get-Date
"Day: " + $a.Day
"Month: " + $a.Month
"Year: " + $a.Year
"Hour: " + $a.Hour
"Minute: " + $a.Minute
"Second: " + $a.Second

When we ran this script on October 25, 2007 at 1:50:4 we got back the following:

Day : 25
Month : 10
Year : 2007
Hour : 13
Minute: 50
Second: 4

See how easy it is? We simply specify the date-time property we’re interested in, and PowerShell takes care of the rest. If all we care about is a single one of these properties – for example, just the day – we could even do this in a single line of code:

$a = (Get-Date).Day

Nothing too fancy here: we simply call the Get-Date cmdlet, enclosing the cmdlet in parentheses to ensure that PowerShell goes out and gets the date before it does anything else. We then grab the value of the Day property, and only the Day property, and assign it to the variable $a. That makes $a equal to this:

25

You know, that was kind of fun, wasn’t it? Let’s try another one. Let’s see if we can extract just the date and just the time:

$a = Get-Date
"Date: " + $a.ToShortDateString()
"Time: " + $a.ToShortTimeString()

And here’s what we get back:

Date: 10/25/2007
Time: 1:55 PM

As you probably noticed, this time around we called a pair of methods: ToShortDateString and ToShortTimeString. But the final result was very similar: we were able to easily extract just a portion of the date-time value.

But we can do more than just grab the seconds or milliseconds from the current date and time. For example, consider these questions:

  • Is it still Daylight Saving Time?

  • I know it’s the 25th, but what day of the week is it?

  • October 25th? What day of the year is that?

So many questions. And Windows PowerShell can provide so many answers … as long as you call the Get-Date cmdlet and request the appropriate property values. You know, like these:

$a = Get-Date
"Daylight Saving Time: " + $a.IsDaylightSavingTime()
"Day of Week: " + $a.DayOfWeek
"Day of Year: " + $a.DayOfYear

Here’s the output from the preceding script:

Daylight Saving Time: True
Day of Week: Thursday
Day of Year: 298

Whoa; less than 70 shopping days until Christmas. If you need to know the Scripting Guys’ sizes and favorite colors, just drop us a line.

Here’s one other little method that might come in handy. Big organizations always face a problem when it comes to dates and times; that’s because the company is likely to span multiple time zones. One way to deal with that issue is to convert dates and times to Universal time; with that approach, you take a local time – like October 25, 2007 at 1:50:45 – and convert that to Greenwich Mean Time. (That is, local time in Greenwich, England rather than your local time.)

Of course, converting a local time to Universal time can be complicated: you need to know your “offset” (the number of hours difference between your time and Greenwich Time); you need to know the direction of that offset (are we 4 hours ahead of Greenwich time or 4 hours behind); you need to deal with Daylight Saving Time vs. Standard Time; you – well, you get the idea. It can be complicated.

Or, it can be very simple:

$a = Get-Date
"Universal Time: " + $a.ToUniversalTime()

As you can see, all we’ve done here is take our local time and applied the ToUniversalTime() method; that will automatically display the local time as Greenwich time. In other words, the time will be displayed like this:

Thursday, October 25, 2007 8:50:04 PM

Like we said, not so complicated after all.

Simple Date Arithmetic

Here’s another cool trick you can play using Get-Date. It’s not unusual for system administrators to be able to see into the future. For example, suppose you’re creating new accounts for seasonal employees. Those accounts are supposed to expire after 90 days. That’s great, except for one thing: what date is 90 days from October 25, 2007?

As it turns out, it’s this date:

Wednesday, January 23, 2008 1:50:04 PM

Before you ask, the Scripting Guys can’t see into the future; if we could, we would have done a little better at predicting who would win this year’s World Series. What we can do, however, is call the AddDays method, passing 90 (for 90 days) as the sole method parameter:

$a = Get-Date
$a.AddDays(90)

Needless to say, that’s going to return a value 90 days from the current date. Would you rather know the date 90 days before the current date? In that case, pass -90 as the sole method parameter:

$a = Get-Date
$a.AddDays(-90)

Give that a try and see what happens.

Incidentally, you’re hardly limited just to adding or subtracting minutes from a date. You also have these methods available to you:

  • AddDays

  • AddHours

  • AddMilliseconds

  • AddMinutes

  • AddMonths

  • AddSeconds

  • AddTicks

  • AddYears

It’s even possible to do even fancier date arithmetic, albeit not with the Get-Date cmdlet. (Instead, you need to use the New-Timespan cmdlet.) But that’s a topic for another week.

PowerShell Bonus: Getting an Array of Day/Month Names

To tell you the truth this has nothing to do with the Get-Date cmdlet, but we decided to tack this on to this week’s tip because we found in interesting. The .NET Framework class System.Globalization.DateTimeFormatInfo is designed to return a ton of information about date-time formatting and configuration on a computer. For example, suppose you run this simple two-line script:

$a = new-object system.globalization.datetimeformatinfo
$a

You’re going to get back information similar to this:

AMDesignator                     : AM
Calendar                         : System.Globalization.GregorianCalendar
DateSeparator                    : /
FirstDayOfWeek                   : Sunday
CalendarWeekRule                 : FirstDay
FullDateTimePattern              : dddd, dd MMMM yyyy HH:mm:ss
LongDatePattern                  : dddd, dd MMMM yyyy
LongTimePattern                  : HH:mm:ss
MonthDayPattern                  : MMMM dd
PMDesignator                     : PM
RFC1123Pattern                   : ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
ShortDatePattern                 : MM/dd/yyyy
ShortTimePattern                 : HH:mm
SortableDateTimePattern          : yyyy'-'MM'-'dd'T'HH':'mm':'ss
TimeSeparator                    : :
UniversalSortableDateTimePattern : yyyy'-'MM'-'dd HH':'mm':'ss'Z'
YearMonthPattern                 : yyyy MMMM
AbbreviatedDayNames              : {Sun, Mon, Tue, Wed...}
ShortestDayNames                 : {Su, Mo, Tu, We...}
DayNames                         : {Sunday, Monday, Tuesday, Wednesday...
AbbreviatedMonthNames            : {Jan, Feb, Mar, Apr...}
MonthNames                       : {January, February, March, April...}
IsReadOnly                       : False
NativeCalendarName               : Gregorian Calendar
AbbreviatedMonthGenitiveNames    : {Jan, Feb, Mar, Apr...}
MonthGenitiveNames               : {January, February, March, April...}

Obviously very useful, especially for those of you working in multi-national organizations.

But pretty much anyone can find a use for the properties DayNames and MonthNames (along with related properties AbbreviatedDayNames, AbbreviatedMonthNames, and ShortestDayNames). What kind of use could you find for these properties? Well, it’s not unusual for script writers to need an array consisting of all the days in a week. If you want to, you can handcraft that array using code similar to this:

$a = "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"

Or, you could let the DateTimeFormatInfo class construct that array for you:

$a = new-object system.globalization.datetimeformatinfo
$b = $a.DayNames
$b

The same thing is true for month names:

$a = new-object system.globalization.datetimeformatinfo
$b = $a.MonthNames
$b

Run this script and you’ll get back the following:

January
February
March
April
May
June
July
August
September
October
November
December

We thought it was kind of cool, too.

See you next week.