Summary: Learn how to use Windows PowerShell to easily get the number of the week of the year.
Microsoft Scripting Guy, Ed Wilson, is here. It seems that at times things appear to be too hard. At other times, things that I figure might be too hard, end up being super simple. I guess this is why I was never that good at project estimation tasks. A case in point is the solar collector that I decided to build for our swimming pool. The first task is to build the frame to support the collectors, then it needs a little plumbing to tie it into the pool. I figured the entire task could be accomplished in one weekend. Six weeks later, the frame itself is not even completed—and that is with Dr. Scripto’s help. The frame and Dr. Scripto appear in the following photo.
Today I decided that I needed to know the number of the week of the year. For example, is this the 23rd week of the year or what? The reason is that I am trying to be 30 days ahead with the Hey! Scripting Guy Blog by the time that December rolls around. Because I publish a new blog every single day, it means that if I want to take a week off, I need to be at least 10 days ahead. This is because I do not like to write, edit, and publish a blog all in the same day. Plus the fact that when I come back from a week of vacation, it takes several days just to get caught up on meeting requests, email, and phone messages. Therefore, I do not want to worry about a Hey! Scripting Guy blog as well when I return from a holiday.
So with all the normal days off in December and in January, coupled with taking a couple weeks of holiday with the Scripting Wife, I always like to be 30 days ahead by the time that December 1 rolls around. This buffer also gives me time to begin working on Scripting Games events, which takes an awful lot of work as well.
At first I figured that I should be able to get the week of the year by using Get-Date. I knew there was the DayOfYear property, so I figured there might be a WeekOfYear property as well. Unfortunately, such was not the case. The Get-Member command and its associated output are shown here.
PS C:\Users\ed> get-date | gm
TypeName: System.DateTime
Name MemberType Definition
—- ———- ———-
Add Method System.DateTime Add(System.TimeSpan value)
AddDays Method System.DateTime AddDays(double value)
AddHours Method System.DateTime AddHours(double value)
AddMilliseconds Method System.DateTime AddMilliseconds(double value)
AddMinutes Method System.DateTime AddMinutes(double value)
AddMonths Method System.DateTime AddMonths(int months)
AddSeconds Method System.DateTime AddSeconds(double value)
AddTicks Method System.DateTime AddTicks(long value)
AddYears Method System.DateTime AddYears(int value)
CompareTo Method int CompareTo(System.Object value), int CompareTo(System.DateTime value)
Equals Method bool Equals(System.Object value), bool Equals(System.DateTime value)
GetDateTimeFormats Method string[] GetDateTimeFormats(), string[] GetDateTimeFormats(System.IFormatProvide…
GetHashCode Method int GetHashCode()
GetType Method type GetType()
GetTypeCode Method System.TypeCode GetTypeCode()
IsDaylightSavingTime Method bool IsDaylightSavingTime()
Subtract Method System.TimeSpan Subtract(System.DateTime value), System.DateTime Subtract(System…
ToBinary Method long ToBinary()
ToFileTime Method long ToFileTime()
ToFileTimeUtc Method long ToFileTimeUtc()
ToLocalTime Method System.DateTime ToLocalTime()
ToLongDateString Method string ToLongDateString()
ToLongTimeString Method string ToLongTimeString()
ToOADate Method double ToOADate()
ToShortDateString Method string ToShortDateString()
ToShortTimeString Method string ToShortTimeString()
ToString Method string ToString(), string ToString(string format), string ToString(System.IForma…
ToUniversalTime Method System.DateTime ToUniversalTime()
DisplayHint NoteProperty Microsoft.PowerShell.Commands.DisplayHintType DisplayHint=DateTime
Date Property System.DateTime Date {get;}
Day Property System.Int32 Day {get;}
DayOfWeek Property System.DayOfWeek DayOfWeek {get;}
DayOfYear Property System.Int32 DayOfYear {get;}
Hour Property System.Int32 Hour {get;}
Kind Property System.DateTimeKind Kind {get;}
Millisecond Property System.Int32 Millisecond {get;}
Minute Property System.Int32 Minute {get;}
Month Property System.Int32 Month {get;}
Second Property System.Int32 Second {get;}
Ticks Property System.Int64 Ticks {get;}
TimeOfDay Property System.TimeSpan TimeOfDay {get;}
Year Property System.Int32 Year {get;}
DateTime ScriptProperty System.Object DateTime {get=if ((& { Set-StrictMode -Version 1; $this.DisplayHin…
PS C:\Users\ed>
“Major bummer,” I thought. Now I figure it is going to be pain to retrieve the information. I open up MSDN in my Internet Explorer 9 browser, and begin searching. It does indeed look like it will be a pain. I have to create calendar rules, calendar types, and all kinds of culture specific things (such as when the first day of the week appears, and how to determine the first week of the year). Ugh, I hate messing around with all that stuff. Whine whine whine whine whine (as the Scripting Wife would say).
But I am positive that I have seen a week of the year before, and it did not involve a lot of messy .NET Framework programming. I decided to look up the help on Get-Date to be on the safe side before I started all that work. In the –uformat section I found my answer…I can use the %V value for the UFormat parameter. This is shown here where the command tells me that I am in the 23rd week as I write this Hey! Scripting Guy blog.
PS C:\Users\ed> get-date -UFormat %V
23
PS C:\Users\ed>
I decided to write a quick function to return a custom DateTime object. At first, I was only going to return the week of the year, but hey, I might want to know what that week of the year is associated with, and so I incorporated a call to the Add-Member Windows PowerShell cmdlet. The complete Get-ExtendedDate function is shown here.
Get-ExtendedDate Function
function Get-ExtendedDate
{
$a = get-date
add-member -MemberType scriptmethod -name GetWeekOfYear `
-value {get-date -uformat %V} -inputobject $a
$a
} #end function Get-ExtendedDate
In the Get-ExtendedDate function, I first obtain a copy of the System.DateTime object by calling the Get-Date cmdlet. I store the returned object in the $a variable. This is shown here.
$a = get-date
The object stored in the $a variable is the base object upon which I will add an additional member. There are several different types of members to add to an object—I am adding a ScriptMethod member because I want to perform a calculation when the member is called. To use the Add-Member Windows PowerShell cmdlet, I specify the type of member to add, a name for the member, how the member value is obtained, and an object upon which to add the member. The command is shown here.
add-member -MemberType scriptmethod -name GetWeekOfYear `
-value {get-date -uformat %V} -inputobject $a
The last thing I need to do is to return the modified object that is stored in the $a variable, and close my curly brackets as shown here.
$a
} #end function Get-ExtendedDate
When I call the Get-ExtendedDate function, a standard DateTime object is returned. Because it is a standard DateTime, the display specifier returns the standard display. This is shown in the following image.
If I pipe the results of the function to the Get-Member cmdlet, I can tell that the additional member is added to the DateTime object. The command to do this is shown here.
Get-ExtendedDate | get-member
The command and its associated output are shown in the following image.
To access the new ScriptMethod, I have a number of options. The one I have a tendency to use is to call the method directly from the function by using a dotted notation. It sounds more complicated than it is. I use a pair of parentheses to surround the function and then call the method. The only hard part is to remember that I created a method, and therefore an empty pair of parentheses is required at the end of the method name. This is shown here.
PS C:\Users\ed> (Get-ExtendedDate).getWeekOfYear()
23
Of course, one can always store the resulting object into a variable, and call the method that way. This is shown here.
PS C:\Users\ed> $b = Get-ExtendedDate
PS C:\Users\ed> $b.GetWeekOfYear()
23
In fact, it is because you can store the object in a variable that I decided to add my ScriptMethod to the DateTime object in the first place. I can use any of the properties and methods of a normal DateTime object in addition to calling my custom ScriptMethod. For example, I might want to do something like the following:
“Today is $($b.ToShortDateString())”
“There are $(365 – $($b.DayOfYear)) days left in the year.”
“This means there are $(52 – $($b.GetWeekOfYear())) weeks left in the year.”
In short, I have complete access to the DateTime object, and I have access to my new ScriptMethod as well. Dude, that makes for a cool solution. By the way, here are the previous commands and their associated output.
Well, that is all there is to extending the DateTime object to include the GetWeekOfYear ScriptMethod. Join me tomorrow for more Windows PowerShell goodness.
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
0 comments