ok, apparently this coding is fun grin, so I augmented mine to support weeks and parameters, and fixed some bugs. For those wondering, yes I love regex smirk

Code:
alias datediff {
  ; calculate difference between date 1 and date 2, in years,months,(weeks),days,hours,minutes,seconds
  ; usage $datediff(dd/mm/yyyy HH:nn:ss, dd/mm/yyyy HH:nn:ss)
  ; meaning $datediff($date $time, $date $time)
  ; example:  //echo -a $datediff(3/5/2005 20:00:10, 5/10/2000 12:15:20)
  ; ** IMPORTANT: $date uses dd/mm/yyyy, if you want to input mm/dd/yyyy style, 
  ; **   add a third parameter 'u'
  ; other parameters
  ;  w = use weeks
  ;  a = display all fields, also 0 values
  ;  s = short duration identifiers
  ;  n = no spaces between numbers and durations
  ;  d = only numbers, no durations (use 'a' too or you won't have a clue what it means ;)
  ;  z = zeropad fields years(4) months(2) weeks(1) days(1) hours(2) minutes(2) seconds(2)
  ; example:  //echo -a $datediff(1/5/2005 11:15:22pm, 1/8/2005 12:15:22P.M., uws)
  ; hh:nn:ss am/pm is supported (only now I realize how strange it actually is)
  ; my reference: http://www.worldtimezone.com/wtz-names/wtz-am-pm.html

  var %1 = $1, %2 = $2, %switched = $false
  :dateswitch
  if ($regex(%2,/^0*(\d+)\D0*(\d+)\D(\d+)\D0*(\d+)\D0*(\d+)\D0*(\d+)(?:\D?([ap]\.?m\.?|noon|midday|midnight))?$/i)) {
    var %d1 = $regml($iif(u isin $3,2,1)), %m1 = $regml($iif(u isin $3,1,2))
    var %h1 = $regml(4), %n1 = $regml(5), %s1 = $regml(6), %y1 = $regml(3)
    if ((%h1 == 12) && (($regml(7) == am) || ($v1 == midnight))) var %h1 = 0
    elseif ((%h1 isnum 1-11) && ($regml(7) == pm)) inc %h1 12
  }
  else return Date 1 in incorrect format
  if ($regex(%1,/^0*(\d+)\D0*(\d+)\D(\d+)\D0*(\d+)\D0*(\d+)\D0*(\d+)(?:\D?([ap]\.?m\.?|noon|midday|midnight))?$/i)) {
    var %d2 = $regml($iif(u isin $3,2,1)), %m2 = $regml($iif(u isin $3,1,2))
    var %h2 = $regml(4), %n2 = $regml(5), %s2 = $regml(6), %y2 = $regml(3)
    if ((%h2 == 12) && (($regml(7) == am) || ($v1 == midnight))) var %h2 = 0
    elseif ((%h2 isnum 1-11) && ($regml(7) == pm)) inc %h2 12
  }
  else return Date 2 in incorrect format
  if ((%m1 !isnum 1-12) || (%d1 !isnum 1-31) || (%h1 !isnum 0-23) || (%m1 !isnum 0-59) $&
    || (%s1 !isnum 0-59)) return Date 1 invalid
  if ((%m2 !isnum 1-12) || (%d2 !isnum 1-31) || (%h2 !isnum 0-23) || (%m2 !isnum 0-59) $&
    || (%s2 !isnum 0-59)) return Date 2 invalid
  var %s = %s1 - %s2 | if (%s < 0) var %s = %s + 60, %n1 = %n1 - 1
  var %n = %n1 - %n2 | if (%n < 0) var %n = %n + 60, %h1 = %h1 - 1
  var %h = %h1 - %h2 | if (%h < 0) var %h = %h + 24, %d1 = %d1 - 1
  var %d = %d1 - %d2
  if (%d < 0) var %d = %d + $gettok(31 $iif((!$calc(%y1 % 400)) || (($calc(%y1 % 100)) $&
    && (!$calc(%y1 % 4))),29,28) 31 30 31 30 31 31 30 31 30 31,%m1,32), %m1 = %m1 - 1
  var %m = %m1 - %m2, %y = %y1 - %y2, %w
  if (%m < 0) var %m = %m + 12, %y = %y - 1
  if (%y < 0) { if (%switched) return ERROR | var %1 = $2, %2 = $1, %switched = $true | goto dateswitch }

  if ( w  isin $3) var %w = $int($calc(%d / 7)) weeks, %d = $calc(%d - 7 * %w)
  if ( z  isin $3) var %y = $base(%y,10,10,4), %m = $base(%m,10,10,2), %d = $base(%d,10,10,2), $&
    %h = $base(%h,10,10,2), %n = $base(%n,10,10,2), %s = $base(%s,10,10,2)
  var %res = %y years %m months %w %d days %h hours %n minutes %s seconds
  if ((a !isin $3) && ( $regsub(%res,/(?<!\d)0 \w++/g,,%res) )) { }
  if ( s  isin $3) { var %res = $replace(%res,year,yr,month,mth,week,wk,hour,hr,minute,min,second,sec) }
  $null($regsub(%res,/(?<!\d)(1 \w+)s(?!\w)/g,\1,%res))
  if ((n  isin $3) && ( $regsub(%res,/(?<=\d)\s+(?=\w)/g,,%res) )) { }
  if ((d  isin $3) && ( $regsub(%res,/\w/g,,%res) )) { }
  return %res
}

Here's what I use as testing between your code and mine
Code:
//var %d1 = 1/1/2007 14:00:00, %d2 = 2/2/2006 13:01:01 | echo -s dftf____ $Duration.From.To.Format(%d1, %d2) | echo -s datediff $datediff(%d1,%d2,nws)

Yes, it gives different output, I think it's not my problem but yours :tongue: (change both a year to the future too)
Also, 2000 is a leap year, you didn't consider that. I did steal your $gettok concept tho smile