pb中關於datetime的函數,總是把date和time分開來處理,沒有針對datetime進行直接增減的函數,在實際使用中限制較大。
用過MS SQL的程序員,都恨不得能夠把MS SQL中的dateadd及datediff函數搬過來用,但是這是不可能的,除非sybase意識到這一點。
下面這個函數f_dateadd ,可以實現MS SQL的dateadd的所有功能,用法也是一樣的(不過,第1個參數必須加上引號)。同時為了兼容pb本身的date類型,該函數還支持參數類型為date的日期的計算。如:f_dateadd( 'hh', 49, 2011-11-04) ,表示計算日期2011-11-04 (默認為0點)的49小時候的日期,函數返回的將是2011-11-06
global function any f_dateadd (string as_type, long ai, any aa_date);
//在向指定日期(date或datetime)加上一段時間的基礎上,返回新的日期(date或datetime)值(與MSSQL的dateadd函數類似)
choose case lower(as_type)
case 'hour','hh' //小時
return f_dateadd('s', ai * 3600, aa_date)
case 'minute','mi','n' //分鐘
return f_dateadd('s', ai * 60, aa_date)
case else
end choose
int li_t
long li
string ls
datetime ldt
date ld
time lt
boolean lb_date = false
any la_return
choose case classname(aa_date)
case 'datetime'
ldt = aa_date
ld = date(ldt)
lt = time(ldt)
la_return = datetime(blob('1900-01-01 00:00:00'))
case 'date'
ld = aa_date
lt = time('00:00:00')
ldt = datetime(ld, lt)
la_return = 1900-01-01
lb_date = true
case else
return datetime(blob('1900-01-01 00:00:00'))
end choose
if ai = 0 then goto label
choose case lower(as_type)
case 'year','yy','yyyy' //年份
li = year(ld) + ai
if li < 1900 or li > 3000 then return la_return
ls = string(li) + string(ld, '-mm-dd')
case 'quarter','qq','q' //季度
li = month(ld) + 3 * ai
if mod(li,12) = 0 then
li_t = -1
else
li_t = li
end if
ls = string(year(ld) + int((li -1) / 12)) + string(mod(li, 12) - 6 * (sign(li) - 1), '-00') + string(ld, '-dd')
case 'month','mm','m' //月份
li = month(ld) + ai
if mod(li,12) = 0 then
li_t = -1
else
li_t = li
end if
ls = string(year(ld) + int((li -1) / 12)) + string(mod(li, 12) - 6 * (sign(li) - 1), '-00') + string(ld, '-dd')
case 'day','dd','d' //天數
ld = RelativeDate ( ld, ai )
goto label
case 'week','wk','ww' //周數
ld = RelativeDate ( ld, ai * 7 )
goto label
case 'hour','hh' //小時
case 'minute','mi','n' //分鐘
case 'second','ss','s' //秒
li = int(ai / 86400)
choose case SecondsAfter ( time(00:00:00), lt ) + mod(ai , 86400)
case is < 0
li --
case is > 86400
li ++
end choose
ld = f_dateadd('day', li, ld)
ls = string(lt, 'fff') //記錄毫秒
lt = RelativeTime(lt, mod(ai , 86400))
lt = time(string(lt, 'hh:mm:ss.') + ls)
goto label
case 'millisecond','ms' //毫秒
li = int(ai / 1000)
ai = integer(string(lt,'fff')) + mod(ai , 1000)
choose case ai
case is < 0
li --
ai = ai + 1000
case is > 1000
li ++
ai = ai - 1000
end choose
if lb_date then
return f_dateadd('s', li, aa_date)
else
return f_dateadd('s', li, datetime(ld, time(string(lt, 'hh:mm:ss.') + string(ai))))
end if
case else
return aa_date
end choose
if ls = '1900-01-01' then return la_return
ld = date(ls)
if ld = 1900-01-01 then ld = f_dateadd('dd', -1, f_dateadd('mm', 1, date(left(ls, 8) + '01')))
label:
if lb_date then
return ld
else
return datetime(ld, lt)
end if
end function
在網上搜了一下,發現已經有人寫過f_dateadd函數了,大家可以自己看看
http://www.BkJia.com/database/201202/119970.html
作者 yyoinge的專欄