GOMONTH(dExpression | tExpression, nNumberOfMonths);
對於給定的日期或日期時間,傳回其指定之前或之後月份數目的日期。
參數說明:
- dExpression | tExpression:輸入 Date 或是 DateTime 資料型態
- nNumberOfMonths:正數表示加給個月份;負數代表減幾個月。
備註: GOMONTH() 不支援 1753年01月01日之前的日期
- 計算月份的最後一天、當月總共有幾天
LOCAL dDate,dLastDay AS date
LOCAL iTotalDay AS integer
dDate = DATE() -- 使用者自訂日期
-- 先利用DATE() 來找出自訂日期月份的第一天,
-- 然後利用GOMONTH() 加一個月找到下個月第一天,
-- 再減一天,找到自訂日期月份的最後一天。
dMonthLastDate = GOMONTH(DATE(YEAR(dDate),MONTH(dDate),1),1)-1
-- 邏輯同上,最後再利用DAY()函數把天數抓出來就行
iTotalDay = DAY(dMonthLastDate)
- 精準計算年紀的年月日(計算兩個日期間的年月日)
1年並不一定是365天,但是1年一定是12個月吧,因此利用計算月份來計算,就可以精準地計算出年月日。這個邏輯延伸,還可以計算到55歲、65歲、年資15年和年資25年還有多久的年月日資料,其實就是計算兩個日期的年月日資料。
FUNCTION CountYYMMDD(tdStartDate AS date,tdEndDate AS date) AS string
LOCAL cYYMMDD AS string
LOCAL iTotalMonth,iYear,iMonth,iDay AS integer
LOCAL dDate AS date
-- GOMONTH() 函數不支援 17530101 之前的日期
IF tdStartDate < {^1753/01/01} OR tdEndDate < {^1753/01/01}
RETURN ""
ENDIF
iTotalMonth = 0
iYear = 0
iMonth = 0
iDay = 0
dDate = tdStartDate -- 迴圈日期;此變數用來跑迴圈,紀錄起始日期
-- 從起始日期計算有幾個月到結束日期
-- 迴圈日期 小於 結束日期,就一直進入
DO WHILE dDate < tdEndDate
dDate = GOMONTH(dDate,1) -- 迴圈日期,一次加一個月
DO CASE
CASE dDate <= tdEndDate
-- 當迴圈日期小於結束日期,iTotalMonth 加 1
iTotalMonth = iTotalMonth + 1
CASE dDate > tdEndDate
-- 當迴圈日期大於結束日期,把迴圈日期 減 1 個月,並離開
-- 此時迴圈日期為最接近結束日期的月份時間
dDate = GOMONTH(dDate,-1)
EXIT
ENDCASE
-- 防呆,避免無限迴圈
IF iTotalMonth > (999*12) + 11
RETURN ""
ENDIF
ENDDO
iYear = INT(iTotalMonth/12)
iMonth = iTotalMonth - (12 * iYear)
iDay = tdEndDate - dDate -- 結束日期 減 迴圈日期(此時為最接近結束日期的月份時間)
cYYMMDD = PADL(ALLTRIM(STR(iYear)),3,"0") + PADL(ALLTRIM(STR(iMonth)),2,"0") + PADL(ALLTRIM(STR(iDay)),2,"0")
RETURN cYYMMDD
ENDFUNC
- 參考資料
- Age()
- GOMONTH()、DATE()、DAY() in VFP 9.0 Help
2 則留言:
真利害!...加油阿!對於年份日期,怎麼感覺有點怪怪的...邏輯是怎麼去推算?應該說年資是怎麼算的?是以在公司服務的天數來算,還是以在公司服務的月數來算?
TO C.C.L ~~
1. 邏輯上面有寫阿,哪裡看不懂嗎?
2. 年月份資料,看你怎麼應用和讓使用者閱讀,我整理好之後,以年資來說,會變成從到職日至欲計算日期(使用者可以自行輸入,預設值是今天),年資為X年X月X日 ~~
張貼留言