Chiquilin Site■10.05.09_Excel:DATEDIF関数のバグ対策

その1:DATEDIF関数のバグについて
その2:Y・M・MD・YD・MD・D対応
ChiquilinSite
DATEDIF関数の単位指定「MD」「YD」にバグ(と呼んでいいのかは分かりませんが この先は便宜上「バグ」と書きます)があることは随分前から指摘されていますが DATEDIFを使わずに他の数式の組み合わせで対処しているものを見たことがありません。それが果たしてバグ対策と呼んでいいのかは分かりませんが 日本の法律に準拠する形(初日不算入/末日参入。※年齢計算の場合は初日参入)にするだけなら 数式で対応すること自体は難しくないと思います。

DATEDIF関数のバグについて

「バグ」と単純に云っていますが 私はアメリカの法律はさっぱり分かりません。もしかしたら他の国ではあれで正しい……なんてことはないでしょうね。MDの結果がマイナスになることもありますから。まず日本の法律のおさらいです。民法 第一編 第六章 期間の計算(第138条―第143条)に期間計算についての記述があります。
◆第百四十条
日、週、月又は年によって期間を定めたときは、期間の初日は、算入しない。ただし、その期間が午前零時から始まるときは、この限りでない。
 
◆第百四十三条
週、月又は年によって期間を定めたときは、その期間は、暦に従って計算する。
2  週、月又は年の初めから期間を起算しないときは、その期間は、最後の週、月又は年においてその起算日に応当する日の前日に満了する。ただし、月又は年によって期間を定めた場合において、最後の月に応当する日がないときは、その月の末日に満了する。
「初日を算入しない」という点については DATEDIF関数もそうなっているので問題ありません。ポイントになるのは 143条の第二項です。例えば
開始日が「2010/1/31」終了日が「2010/2/28」の場合
=DATEDIF(開始日,終了日,"YM") →結果は「0」
=DATEDIF(開始日,終了日,"M")  →結果は「0」
=DATEDIF(開始日,終了日,"MD") →結果は「28」
となりますが 民法 143条のルールに従うなら 結果はそれぞれ「1」「1」「0」になるのが正しいはずです。もしくは
開始日が「2008/1/31」終了日が「2010/3/2」の場合
=DATEDIF(開始日,終了日,"MD")  →結果は「-1」
=DATEDIF(開始日,終了日,"YD") →結果は「30」
となります。考えれば分かりますが 期間が「-1」になるはずがありません。正しくは「2」「31」です。つまり Excelの DATEDIF関数の単位「MD」「YD」は時によっては計算結果を正しく返しません。上記の通り「MD」「YD」の結果次第では「Y」「YM」「M」も同様に影響を受けます。また Excel2007については SP2にしておかないと更に違った結果になりますのでご注意下さい。
[10.05.28 追加訂正]2007は SP2の時点では まだ以前の計算には戻らないようです……
ktDATEDIF , DATEDIF(Excel2003以前) , DATEDIF(Excel2007 SP無,SP1 ) での算出結果の違い
DATEDIF関数を使ってそのバグ対策を行う方法については 角田さんのホームページ AddinBox(Main)の「kt関数Ref:ktPeriodYMD DATEDIFによる期間計算」を参考にして下さい。
ページの一番上へ

その2:Y・M・MD・YD・MD・D対応

それでは DATEDIF関数を使わずに 別の数式で法律に準拠した計算をしてみましょう。
尚 数式を見やすくするために 開始日を「始」終了日を「終」としています。
◆Y
=INT((YEAR(終)*12+MONTH(終)-YEAR(始)*12-MONTH(始)
-IF(DAY(始+1)=1,IF(DAY(終+1)>1,1),
IF(AND(DAY(終+1)>1,DAY(終)<DAY(始)),1)))/12)
→「=INT(【Mの数式】/12)
◆YM
=MOD(YEAR(終)*12+MONTH(終)-YEAR(始)*12-MONTH(始)
-IF(DAY(始+1)=1,IF(DAY(終+1)>1,1),
IF(AND(DAY(終+1)>1,DAY(終)<DAY(始)),1)),12)
→「=MOD(【Mの数式】,12)
◆M
=YEAR(終)*12+MONTH(終)-YEAR(始)*12-MONTH(始)
-IF(DAY(始+1)=1,IF(DAY(終+1)>1,1),
IF(AND(DAY(終+1)>1,DAY(終)<DAY(始)),1))
◆MD
=IF(DAY(終+1)=1,MOD(MAX(DAY(終)-DAY(始+1)+1,0),DAY(終)),
IF(DAY(始+1)=1,DAY(終),MOD(DAY(終)-DAY(MIN(DATE(YEAR(終),
MONTH(終)-{1,0},DAY(始)*{1,0}))+1)+1,DAY(終-DAY(終)))))
◆YD
=MOD(終-始,MAX(INT((YEAR(終)*12+MONTH(終)-YEAR(始)*12-MONTH(始)
-IF(DAY(始+1)=1,IF(DAY(終+1)>1,1),
IF(AND(DAY(終+1)>1,DAY(終)<DAY(始)),1)))/12),1)*365)
→「=MOD(【Dの数式】,MAX(【Yの数式】,1)*365)
◆D
=終-始
以上です。実際には同じような計算が多数ありますので いちいちひとつずつ律儀に計算する必要はないでしょう。 →参考ファイル(044.xlsx)
ページの一番上へ
ChiquilinSite トップページへ  Copyright(C) Chiquilin_site. All Rights Reserved.
inserted by FC2 system