Scripting Games, Beginner Event 5, What’s the Difference

Take a date parameter in the form "March 3, 2008" and display the difference from today’s date in various contrived formats…

Although this worked OK for me apparently the Scripting Guys didn’t like it much as I got a 0 – ho hum!  Maybe it doesn’t work in US timezones – or maybe I just messed up the submission?  Or maybe it’s just wrong?!  If you can see why it might be broken please post a comment – thanks!

  1 # Collect all the supplied arguments and join them together as strings...
  2 # We're hoping to be passed "March 3, 2009" (but without the quotes, unfortunately!)
  3 $Args|%{$s=""}{$s+=[string]$_+" "}
  4 
  5 $d=Get-Date($s)	# Hopefully the resulting parameter string will turn out to be a valid date
  6 
  7 $now=Get-Date
  8 
  9 $MonthsDifference=($d.year-$now.Year)*12+$d.Month-$now.Month-1
 10 $MonthDaysDifference=($d-$now.AddMonths($MonthsDifference)).days
 11 
 12 "Days: $(($d-$now).days)"
 13 "Months: $(($d.year-$now.year)*12+$d.month-$now.month)"
 14 "Month/Days: $($MonthsDifference)/$MonthDaysDifference"

This does illustrate one of the foibles of PowerShell’s argument handling; while it is undoubtedly a Good Thing to have unified parameter parsing that’s handled for you automatically, it can be a nuisance when the specific requirements need something else.  In this case we need to take the complete parameter string and pass it to Get-Date to convert it to a date type*.  This would be fine if the whole parameter string were enclosed in quotes, but since we can’t rely on that we have to piece together the individual chunks from $args[].  In a good-old batch file we can get the full argument list in a single variable, but not in PS!

We could, instead, get the line used to invoke the script from $MyInvocation.line and split off the script name from the start of the line, but this fails if the script was called from a line like (for example):

> $a=script parm1 parm2; $a.length

In this case the information from $MyInvocation.line includes the WHOLE line (including the second statement after the ";").  Once again, we could do a bit more (potentially complex) parsing to eliminate all but the section we are interested in, but this starts to get very messy.

Thankfully this situation is improved (somewhat) with V2 (although maybe I should get onto Connect and request an $AllArgs variable:-)

 

* <rant> Oh, BTW, we could use a cast to [datetime] but in general casts to this type are best avoided (even if you do live in the US) thanks to the horribly broken format the PS team sprung on us at the very end of the V1 beta :-(   </rant>

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s