Ok. Here is a new version that uses a different algorithm. If DATE1 is the only parameter provided it will return the Chronological Julian Day Number if, for some reason, you need that.
Code:
;
;Function:
; fnDateDiff()
;
;Author:
; Christopher Shilt (gk_zone@hotmail.com)
;
;Contributors:
; Jochen Polster (jochenDOTpolsterATgmxDOTnet)
;
;Version:
; 1.0 (October 3, 2006)
;
;Version History:
;
;Action:
; Calculates a specified interval between two dates or returns the date/time difference
; of a specified interval.
;
;Syntax:
; fnDateDiff(DATE1, [DATE2|INTEGER], [INTERVAL], [FIX])
;
;Parameters:
; DATE1 : Required. Gregorian datetime in YYYY/M[M]/D[D] [HH:MM:SS] format.
; Note: Time is not required, if omitted 00:00:00 (midnight) will be
; used.
;
; DATE2|INTERVAL : Optional. Gregorian datetime in YYYY/M[M]/D[D] [HH:MM:SS] format or
; positive or negative integer to add to DATE1.
;
; INTERVAL : Optional. Type of interval to add to DATE1. Supported formats are:
;
; S : Seconds
; M : Minutes
; H : Hours
; D : Days
; W : Weeks
;
; FIX : Optional. Removes the fractional part of number and returns the
; resulting integer value.
;
;Remarks:
;
; Based on date algorithms by Henry F. Fliegel and Thomas C. Van Flandern
; (http://hermetic.nofadz.com/cal_stud/jdn.htm#comp)
;
;Returns:
;
; The Chronological Julian Day Number of DATE1 if no other parameter is used.
;
; The Datetime string of an interval added to DATE1 if an INTERVAL is the second parameter.
;
; The difference (positive or negative) between two given datetimes if DATE2 is the second
; parameter.
;
; Sets the value of @ERROR based on success/failure.
;
;Dependencies:
;
;
;Example:
;
; "One second after midnight: " + fnDateDiff(@DATE,1,"s") ?
; "One second before midnight: " + fnDateDiff(@DATE,-1,"s") ?
; "Seconds between today and tomorrow: " + fnDateDiff(@DATE,fnDateDiff(@DATE,1,"d"),"s",0) ?
; "Weeks between today and six days from today: " + fnDateDiff(@DATE,fnDateDiff(@DATE,6,"d"),"w",0) ?
; "Weeks (fixed) between today and six days from today: " + fnDateDiff(@DATE,fnDateDiff(@DATE,6,"d"),"w",1) ?
; "Shopping days until my birthday: " + fnDateDiff(@DATE,"2007/04/20","d") ?
; "Seconds between 1/1/1601 and 1/1/1970: " + fnDateDiff("1601/01/01","1970/01/01","s") ?
; "Hours between NOW and 5:00PM today: " + fnDateDiff(@DATE+' '+@TIME,@DATE+' '+"17:00:00","h") ?
; "Hours between 5:00PM today and NOW: " + fnDateDiff(@DATE+' '+"17:00:00",@DATE+' '+@TIME,"h") ?
; "Yesterday's date: " + fnDateDiff(@DATE,-1,"d") ?
; "Seconds between midnight and 11:59:59 pm: " + fnDateDiff("00:00:00","23:59:59","s") ?
; "Seconds between 11:59:59 pm and midnight: " + fnDateDiff("23:59:59","00:00:00","s") ?
; "Add one minute to midnight: " + fnDateDiff("00:00:00",1,"m",0) ?
; "VarTypeName of fnDateDiff output: " + VarTypeName(fnDateDiff(@TIME,0,"s")) ?
; "VarTypeName of @@TIME: " + VarTypeName(@TIME) ?
; "The Chronological Julian Day Number of 2003/11/08 18:00:00 is: " + fnDateDiff("2003/11/08 18:00:00") ?
; "Today is: "
; $weekday = fnDateDiff(@DATE) mod 7
; Select
; Case $weekday = 0 "Monday" ?
; Case $weekday = 1 "Tuesday" ?
; Case $weekday = 2 "Wednesday" ?
; Case $weekday = 3 "Thursday" ?
; Case $weekday = 4 "Friday" ?
; Case $weekday = 5 "Saturday" ?
; Case $weekday = 6 "Sunday" ?
; EndSelect
; @ERROR " | " @SERROR ?
; ? "Press any key to continue." Get $
;
Function fnDateDiff($DateTime,Optional $DateOrInterval,$Interval,$Fix)
Dim $Date1,$Date2,$jDate[2],$jTime[2],$y,$m,$d,$ss,$mm,$hh,$i,$l,$n,$j
$Date1=Split($DateTime," ")
If UBound($Date1)>1 Exit 1901 EndIf
If UBound($Date1)=0
Select
Case InStr($Date1[0],"/") $jDate=Split($Date1[0],"/")
Case InStr($Date1[0],":")
$jDate=Split("1899/12/30","/")
$jTime=Split($Date1[0],":")
Case 1 Exit 1901
EndSelect
Else
If InStr($Date1[0],"/") and InStr($Date1[1],":")
$jDate=Split($Date1[0],"/")
$jTime=Split($Date1[1],":")
Else
Exit 1901
EndIf
EndIf
$y=Val($jDate[0]) If $y=0 Exit 1901 EndIf
$m=Val($jDate[1]) If $m<1 or $m>12 Exit 1901 EndIf
$d=Val($jDate[2]) If $d<1 or $d>31 Exit 1901 EndIf
$jDate = CDbl((1461*($y+4800+($m-14)/12))/4+(367*($m-2-12*(($m-14)/12)))/12-
(3*(($y+4900+($m-14)/12)/100))/4+$d-32075)
$jTime = CDbl((Val($jTime[0])*3600)+(Val($jTime[1])*60)+Val($jTime[2]))/86400
If $jTime=>1 Exit 1901 EndIf
$Date1=CDbl($jDate+$jTime)
If VarType($DateOrInterval)
If InStr($DateOrInterval,"/") or InStr($DateOrInterval,":")
$Date2=fnDateDiff($DateOrInterval)
$fnDateDiff=($Date2-$Date1)*86400
Select
Case $Interval="s"
Case $Interval="m" $fnDateDiff=$fnDateDiff/60
Case $Interval="h" $fnDateDiff=$fnDateDiff/3600
Case $Interval="d" $fnDateDiff=$fnDateDiff/86400
Case $Interval="w" $fnDateDiff=$fnDateDiff/604800
Case 1 Exit 87
EndSelect
If $Interval="s" $fnDateDiff=CInt($fnDateDiff) EndIf
If $Fix $fnDateDiff=Fix($fnDateDiff) EndIf
Else
If VarType($DateOrInterval)>5 Exit 87 EndIf
Select
Case $Interval="s" If VarType($DateOrInterval)>3 Exit 87 EndIf
Case $Interval="m" $DateOrInterval=$DateOrInterval*60
Case $Interval="h" $DateOrInterval=$DateOrInterval*3600
Case $Interval="d" $DateOrInterval=$DateOrInterval*86400
Case $Interval="w" $DateOrInterval=$DateOrInterval*604800
Case 1 Exit 87
EndSelect
$fnDateDiff=$Date1+($DateOrInterval/86400)
$jTime=$fnDateDiff-Fix($fnDateDiff)
$jDate=Fix($fnDateDiff)
$l = $jDate+68569 $n = (4*$l)/146097 $l = $l-(146097*$n+3)/4
$i = (4000*($l+1))/1461001 $l = $l-(1461*$i)/4+31 $j = (80*$l)/2447
$d = $l-(2447*$j)/80 $l = $j/11 $m = $j+2-(12*l) $y = 100*($n-49)+$i+$l
If $m>12 $m=$m-12 EndIf
If $y<0 $y=$y*-1 $y=Right("-000"+$y,5) Else $y = Right("000"+$y,4) EndIf
$m = Right("0"+$m,2)
$d = Right("0"+$d,2)
$ss = CInt(86400.0*$jTime)
$mm=$ss/60 $ss=$ss mod 60 $hh=$mm/60 $mm=$mm mod 60
$jDate=Iif($y,''+$y+'/'+$m+'/'+$d,'')
$jDate=Iif($y=1899 & $m=12 & $d=30,'',$jDate)
$jTime=Iif($jTime,Right("0"+$hh,2)+':'+Right("0"+$mm,2)+':'+Right("0"+$ss,2),'')
$fnDateDiff=Iif($jDate & $jTime,$jDate+" "+$jTime,$jDate+$jTime)
EndIf
Else
$fnDateDiff=$Date1
EndIf
EndFunction