Get-OtherDate

PowerShell’s [DATETIME] object has some handy methods for calculating a date such as AddDays().

PS C:\> get-date

Wednesday, September 03, 2008 4:11:18 PM

PS C:\> (get-date).AddDays(23)

Friday, September 26, 2008 4:11:34 PM

PS C:\>

You can even subtract by adding a negative number:

PS C:\> (get-date).AddHours(-67)

Sunday, August 31, 2008 9:14:40 PM

The [DATETIME] object also allows you to add a TimeSpan like this:

PS C:\> [datetime]$d="2/22/2008 5:00AM"
PS C:\> #Add 2 days
PS C:\> $d.Add("2:0:0") Friday, February 22, 2008 7:00:00 AM PS C:\> #Add 34 minutes PS C:\> $d.Add("0:34:0") Friday, February 22, 2008 5:34:00 AM PS C:\> #Add 15 seconds PS C:\> $d.Add("0:0:15") Friday, February 22, 2008 5:00:15 AM PS C:\> #Add 2 days, 3 hours and 15 min
PS C:\> $d.Add("2:3:15") Friday, February 22, 2008 7:03:15 AM

This is all nice. But what if you wanted to calculate a more complex date time, perhaps one in years? There is an AddYears() method. Although none of this will help if you want to calculate a date that is 1 year, 2 months  and 1 day from now. For those situations, or if you want a simpler approach instead of calling methods, I wrote the Get-OtherDate function.

   1: Function Get-OtherDate {
   2:     Param([datetime]$date=(Get-Date),
   3:           [int32]$years=0,
   4:           [int32]$months=0,
   5:           [int32]$days=0,
   6:           [int32]$hours=0,
   7:           [int32]$minutes=0,
   8:           [int32]$seconds=0,
   9:           [int32]$milliseconds=0
  10:           )
  11:           
  12:     [datetime]$dt=$date   
  13:     if ($milliseconds -ne 0) {$dt=$dt.AddMilliseconds($milliseconds)}
  14:     if ($seconds -ne 0) {$dt=$dt.AddSeconds($seconds)}
  15:     if ($minutes -ne 0) {$dt=$dt.AddMinutes($minutes)}
  16:     if ($hours -ne 0) {$dt=$dt.AddHours($hours)}
  17:     if ($days -ne 0) {$dt=$dt.AddDays($days)}     
  18:     if ($months -ne 0) {$dt=$dt.AddMonths($months)}
  19:     if ($years -ne 0) {$dt=$dt.AddYears($years)}
  20:  
  21:     write $dt          
  22:   
  23: }

The function takes as parameters a starting date ($date) and then one or more parameters for time intervals such as -days, -hours or -minutes.  You don’t have to specify a starting date, it will default to the current date and time.  All the function does is call the appropriate [datetime] method and builds a new date time object moving  from the smallest time interval to the largest. Here are some examples of the function in use with the default current date:

PS C:\> get-date

Thursday, September 04, 2008 12:15:43 PM

PS C:\> Get-OtherDate -months 1 -days 11 -hours 7

Wednesday, October 15, 2008 7:15:46 PM

PS C:\> Get-OtherDate -days -45

Monday, July 21, 2008 12:16:08 PM

Here are some samples using a different date:

PS C:\> get-OtherDate 7/4/2008 -days 99

Saturday, October 11, 2008 12:00:00 AM

PS C:\> Get-OtherDate 12:34 -hours 4

Thursday, September 04, 2008 4:34:00 PM

PS C:\> Get-OtherDate 22:34 -hours -4 -minutes -14

Thursday, September 04, 2008 6:20:00 PM

There’s nothing really special here.  All I’ve done is create a shortcut function. An advantage is that I can create an alias (like od) and take advantage of short parameter names. Here’s how this might work in a production environment:

PS C:\> [ADSI]$admin="WinNT://$env:computername/Administrator,user"
PS C:\> $lastset = od -s (-$admin.passwordage.value)
PS C:\> $expires = od $lastset -day 60
PS C:\> Write-host "Password last set $lastSet and expires $expires"
Password last set 09/02/2008 22:29:51 and expires 11/01/2008 22:29:51
PS C:\>

Download the script file here