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
}