Embarcadero Quality PortalのRSP-11694より。
System.DateUtils.MonthsBetween関数は、指定した2つのTDateTime値の間隔が何か月かを返します。
次のコードを実行すると、
uses
System.DateUtils,
System.SysUtils;
begin
WriteLn(MonthsBetween(EncodeDate(2015, 8, 1), EncodeDate(2015, 8, 31)));
WriteLn(MonthsBetween(EncodeDate(2015, 7, 1), EncodeDate(2015, 8, 31)));
WriteLn(MonthsBetween(EncodeDate(2015, 6, 1), EncodeDate(2015, 8, 31)));
WriteLn(MonthsBetween(EncodeDate(2015, 5, 1), EncodeDate(2015, 8, 31)));
WriteLn(MonthsBetween(EncodeDate(2015, 4, 1), EncodeDate(2015, 8, 31)));
WriteLn(MonthsBetween(EncodeDate(2015, 3, 1), EncodeDate(2015, 8, 31)));
end.
実行結果はこのようになります。
0
2
2
4
4
6
納得できない結果ですね。
ちなみにExcelのDATEDIF関数(=DATEDIF(A1, B1, “m”))を使うと、こうなります。
2015/8/1 | 2015/8/31 | 0 |
2015/7/1 | 2015/8/31 | 1 |
2015/6/1 | 2015/8/31 | 2 |
2015/5/1 | 2015/8/31 | 3 |
2015/4/1 | 2015/8/31 | 4 |
リンクされたヘルプに以下の記載があります。
>MonthsBetween は「1 か月=30.4375 日」という想定を基に、近似値を返します。
月によって30日、31日の違いを考慮されていないので、返り値がおかしなものになっているようです。
安易な実装のように思えますが、歴史的経緯があるのかもしれません。
Excelのような賢い関数がDelphiにも欲しいと思います。