西暦1年1月1日からの日数から西暦年月日に変換する部分を修正してみました。
2分探索による挟み込みで該当年月を絞り込みます。
関数DateFrom111は、関数NISSUUに相当します。
FUNCTION IsLeapYear(y) !うるう年の判定 LET IsLeapYear=0 IF (MOD(y,4)=0 AND MOD(y,100)<>0) OR MOD(y,400)=0 THEN LET IsLeapYear=1 !うるう年 END FUNCTION
LET MaxLevel=10000 !最大年数
FUNCTION Year(n) !(西暦1年1月1日からの)日数から西暦の年を得る LET ya=1 !下限 LET yb=MaxLevel !上限 DO UNTIL ya>yb LET y=INT((ya+yb)/2) !中央 IF DateFrom111(y,1,1)<=n THEN !西暦y年1月1日での日数を得る LET ya=y+1 !下限の更新(上半分) ELSE LET yb=y-1 !上限の更新(下半分) END IF LOOP IF DateFrom111(y,1,1)>n THEN LET y=y-1 !超えていたら戻す LET Year=y END FUNCTION
FUNCTION Month(n) !(西暦1年1月1日からの)日数から西暦の月を得る LET y=Year(n) !年 LET ma=1 !2分探索 LET mb=12 DO UNTIL ma>mb LET m=INT((ma+mb)/2) IF DateFrom111(y,m,1)<=n THEN LET ma=m+1 ELSE LET mb=m-1 END IF LOOP IF DateFrom111(y,m,1)>n THEN LET m=m-1 LET Month=m END FUNCTION
FUNCTION Day(n) !(西暦1年1月1日からの)日数から西暦の月を得る LET Day=n-DateFrom111(Year(n),Month(n),1)+1 END FUNCTION
FUNCTION DateFrom111(y,m,d) !西暦1年1月1日からの日数を得る LET yy=y-1 !年 LET a=yy*365+INT(yy/4)-INT(yy/100)+INT(yy/400) FOR i=1 TO m-1 !月 LET a=a+EOMonth(i) NEXT i IF m>2 THEN LET a=a+IsLeapYear(y) !うるう年の補正 LET a=a+d !日 LET DateFrom111=a END FUNCTION
DATA 31,28,31,30,31,30,31,31,30,31,30,31 !各月の日数 DIM EOMonth(12) MAT READ EOMonth !------------------------------ ここまでがサブルーチン
LET n=DateFrom111(2008,1,1) + 365 !n日後 PRINT Year(n) PRINT Month(n) PRINT Day(n)
LET n=DateFrom111(2008,3,1) - 1 !n日前 PRINT Year(n) PRINT Month(n) PRINT Day(n)
END
|