ロゴ(青) Excel/VBA Tips ロゴ(緑)

Tips17: ねぇ、DAYS360でホントに良いの?                                      

Update: 2023/10/19
(1) DAY360 関数 とは何なのか? 何に使うのか? , YEARFRAC 関数
(2) Excel/DAYS360 (NASD)  ,  Excel/DAYS360(NASD)で 30/360(SIA) の計算
(3) Excel/DAYS360 (ヨーロッパ)
(4) MS-KB ドキュメントについて
(5) 30/360 日数計算 の考察 ( 関連文書 : Wikipedia(1) , Wikipedia(2) , FinCAD , WWWFinance , Entisoft Tools , MSRB )
(6) 30/360 日数計算マクロ (VBA , OOo Basic ) , JavaScript による計算
(7) ワークシート関数 LET による算出式 ( Excel 2021 以降 )  2023/10/19 追記  
(8) Excel 他 OOo.Calc / Google_SpreadSheet の DAYS360 , YEARFRAC について

注) DAYS360(NASD) , YEARFRAC(NASD) の計算間違いについて調査し、この件を MS はバグと認めましたが、
     「財務関数(利息計算など)」 にある NASD方式 については検証していません。



[ この場所へのリンク ]
【 DAY360関数とは何なのか? 何に使うのか? 】
  日数計算のQ&Aで
      「DAYS360を使って計算しているのですが‥‥‥」
      「それは、DAYS360を使えば計算できますよ」
という質問/回答を偶に目にします。こういう質問/回答を見かける度に
      「果たして、この質問者/回答者はDAYS360関数の意味を理解した上で使っているのかな?」
と心配になります。

  もしかしたら、そういう人達は「日付(=シリアル値)を単に引算&書式を"標準"にすればOK」と
いうノウハウがあるのを知らないのかもしれないですね。それで、
    ・DAYS360という関数しか見当たらなかった(DATEDIFは隠し関数)為に
      「エクセルでは日数計算にはDAYS360を使うんだ」という思い込みを持ってしまった
とか、
    ・その人も、「日数はDAYS360で計算すれば良いよ」というアドバイスを受けて、そのまま
      疑問を持つことなく使い続け、今度は教える立場で教わった事をそのまま伝えている
だけなのかもしれないですね?

  そうだとしたら、正しい知識として「DAYS360で行なう日数計算とは何なのか」を皆さんに知って
貰う必要がありそうです。ただし、私の言いたい事は、「DAYS360を使ってはいけない」という意味
ではありませんから勘違いしないで下さい。
  何故なら、DAYS360関数による計算を必要とする業務というものも確かにあり、そのような業務に
於いてはDAYS360関数を使う必要がありますし、そのような業務に携わっている人がそのような業
務に係わる質問に対して「DAYS360を使えば良い」というアドバイスをするのも至極まともな事です。

  このトピックで喚起したいのは、
      ・DAYS360を必要とする「業務であるのか否か」を確認する事無く
      ・日本国内において通常行なう日数計算に
      ・単に、DAYS360という関数があるから、それを使えば良い

という安易な考えを持つ事は間違った結果を招き、トラブルを起こす可能性があるから注意が必要
だという事です。実際に計算してみると(下記はNASD方式(FALSE)による算出です)、
   
2006/3/31 〜 2006/4/30
2006/4/30 〜 2006/5/30
2006/4/30 〜 2006/5/31

2006/1/ 1 〜 2006/1/30
2006/1/ 1 〜 2006/1/31
2006/1/ 1 〜 2006/2/ 1
2006/1/ 1 〜 2006/2/ 2
2006/3/29 〜 2006/3/31
2006/3/30 〜 2006/3/31

2006/2/ 1 〜 2006/2/27
2006/2/ 1 〜 2006/2/28
2006/2/ 1 〜 2006/3/ 1
2006/2/ 1 〜 2006/3/ 2

2005/12/30 〜 2006/12/31
2005/12/31 〜 2006/12/31
2006/1/ 1 〜 2006/12/31
2008/1/ 1 〜 2008/12/31

2006/2/28 〜 2006/2/28

DAYS360(初日不算入)
30
30
30

 29
 30
 30
 31
  2
  0

 26
 27
 30
 31

360
360
360
360

-2 (参照)

暦日数(開始日除く)
30
30
31

 29
 30
 31
 32
  2
  1

 26
 27
 28
 29

366
365
364
365

0

こんな風に違います。カレンダーを指折り数えた日数(暦日数)とは違いますね。
  その違いの説明をするには、
      ・日数計算にDAYS360を必要とする業務とは何ですか?
      ・日数計算にDAYS360を使ってはいけない業務とは何ですか?
という事から考える必要があるでしょう。

  先ずは、DAYS360のヘルプを見てください。そこには何と書いてあるでしょうか。
    1年を360日(30日×12)として、支払いの計算などによく使用される2つの
  日付の間の日数を返します。経理システムで1年を30日×12と仮定してい
  る場合、この関数は、支払いの計算などに役立ちます。
ほら、
    【360日/年】という基準で日数をカウントする場合に使って下さい
と書いてありますね。これが即ち、『DAYS360を必要とする業務』です。

  1年は365(366)日なのに5日間も端折ってどうするんだ、そんな業務があるのか、と思う人も居る
かもしれませんが、そういう業務は、ちゃんとあります。そして、DAYS360とは、そういう場合に便利
だろうという観点から用意されているものなのです。

  もう一度ヘルプを見てもらうと
    方式:FALSE/省略        定義:NASD方式。開始日が‥‥‥
と書いてありますね。NASDって何でしょう? 株のニュースで「ナスダック(NASDAQ)」という言葉
はよく耳にすると思いますが、NASDとは「アメリカ証券業協会」のことです。そこが作ったコンピュ
ータによる売買システムを使ったアメリカの株式店頭市場のことをNASDAQと呼びます。このNA
SDの取引規則の中で360日/年という日数計算の定義
がされています。
      IM-2522. Computation of Elapsed Days
      http://finra.complinet.com/en/display/display_main.html&rbid=2403&element_id=3671 ( by Internet Archive )
    Rule 2522. Definitions Related to Options, Currency Warrants,
                        Currency Index Warrants and Stock Index Warrants Transactions
      http://finra.complinet.com/en/display/display.html&rbid=2403&element_id=3670 ( by Internet Archive )
 

  アメリカでは株関連をはじめとして、利率計算などでも360日/年という基準が一般的であるようで
す。それであれば、エクセルがアメリカのMS社の製品であり、また、エクセルが関数体系の手本に
した(真似た)1-2-3もやはりアメリカのロータス社の製品である以上、アメリカ国内で一般的な計算
方法(360日/年)をカバーする機能(DAYS360)を盛り込むのは当然ですね。ですから、アメリカ国内
での日数計算にDAYS360を使うのは極々当たり前な事ですし、この計算の為に使える便利な関数
(DAYS360)が用意されているというのは、とても都合が良い事です。

  しかしながら、日本では360日/年というのは一般的ではありません。日本では、特に定めがない限
り「暦にしたがって計算する」と民法に記されています(「期間計算」を参照して下さい)。即ち、365
(366)日/年です。各々の月の日数も暦の大小閏に従います。これはこれで閏年などと絡んで利率
などの計算の際には厄介な部分がありますが、それは下記リンクを参照して下さい。
   
    ILCジャーナル / 「金利及び弁済金額計算に関する法律と実務」 抜粋
    『金利計算と閏年・端数処理について』 大阪弁護士会所属 弁護士 服部 廣志
    http://www.ilc.gr.jp/journal/000109/ (by Internet Archive )
    補:インターネット法律協議会 ( ILC ) - 2017年5月31日 閉鎖 -


  ネットを検索してみると
      ★  1年を360日として計算する主な国・通貨 ★
              アメリカ、オーストラリア、ニュージーランド、カナダ、スイス、EURO
      ★ 1年を365日として計算する主な国 ★
              日本、イギリス、香港、シンガポール、タイ
という記述がありました。国によって基準は異なるのです。
  ただし、日本国内の業務でも、1年を360日として計算する通貨の外貨建て預金などを計算する
場合には当然360日/年で計算する必要があります。その場合にはDAYS360は有効で便利な関
数といえます。

  つまり
    ・日数計算にDAYS360を必要とする業務とは → 360日/年を基準にしている業務
    ・日数計算にDAYS360を使ってはいけない業務とは → 365(366)日/年を基準にしている業務
ということです(逆にしたら、期待する日数の結果とは食い違ってしまいます)。

  日本国内では365(366)日/年が基本ですから、360日/年と明記していない限り、DAYS360を使う
のは不適当です。では、代わりに何を使えば良いのかといえば、単に
      【 日付を引算(終了日−開始日)して、書式を"標準"
とすれば充分です。深く考える必要はありません。これは"日数"の場合の話です(DAYS360も"日数"
しか計算できません)。

  では、「y年mヶ月d日」という形での期間を求める場合については、どのように処理するのが正しい
のでしょうか。
    -- 360日/年の場合 --
      毎月が30日という前提ですから、DAYS360で求めた日数から月数を得るのも簡単です。
      単に30で割れば総月数(13ヶ月とか)、360で割った余りを30で割れば年未満の満月
      数(1年と1ヶ月とか)が求まります。更にそれの余りが残りの月未満の日数です。

    -- 365(366)日/年の場合 --
      暦にしたがって計算する必要がありますが、これに使えるDATEDIFという関数がちゃんと
      用意されています(隠し関数ですから関数のダイアログには出て来ません。全て手打ちす
      る必要があります)。それを使って
            総月数なら                =DATEDIF(開始日,終了日,"M")
            満年数なら                =DATEDIF(開始日,終了日,"Y")
            年未満の満月数なら  =DATEDIF(開始日,終了日,"YM")
      とすれば求まります。月未満の残りの日数に関しても["MD"]という指定で求まるのですが、
      この部分には非常に有名で且つ非常に厄介なバグを抱えていますので、安易に使うべき
      ではないですね(時にマイナスが返ります)。また、Excel2007では、そのバグが更に悪化
      て全く使い物にならなくなっていますので注意してください。

[ この場所へのリンク ]
---- YEARFRAC 関数 について ----
  他に、期間を「1.5年」などと計算する事もありますね。この場合には、YEARFRAC関数(分析
ツール)がよく紹介されています。
    YEARFRAC関数 のヘルプ
    基準:1年を何日として計算するかを数値で指定します。

   [ 基準 ]      [ 1月の日数/1年の日数 ]
      0/省略      30日/360日 (NASD 方式)    (XL97とXL2000以降では計算結果が一部異なります)
      1              実際の日数/実際の日数     (この計算方式の解説)
      2              実際の日数/360日
      3              実際の日数/365日
      4              30日/360日 (ヨーロッパ方式)
 
  この関数も「30日/360日」という計算方式を持っています。「基準」引数を省略するとNASD方式
で計算しますから国内業務としては相応しくありません。
  他には[基準:1 実日数/実日数]という指定があります。その表現からすると日本国内の業務に合
いそうな気もしますね。"使える"ものなのか、「6ヶ月 , 0.5年」というケースで確認してみましょう。
  (開始日を除く)
2000/1/ 1〜2000/7/ 1
2000/1/ 1〜2000/7/ 2
2000/2/ 1〜2000/8/ 1
2000/2/ 1〜2000/8/ 2
2000/3/ 1〜2000/8/31
2000/3/ 1〜2000/9/ 1

2000/1/10〜2000/7/10
2000/1/10〜2000/7/11
2000/2/10〜2000/8/10
2000/2/10〜2000/8/11
2000/3/10〜2000/9/ 9
2000/3/10〜2000/9/10
暦日数
182
183
182
183
183
184

182
183
182
183
183
184
YEARFRAC
0.4973
0.5000
0.4973
0.5000
0.5000
0.5027

0.4973
0.5000
0.4973
0.5000
0.5000
0.5027
Y年Mヶ月D日
0年6ヶ月 0日
0年6ヶ月 1日
0年6ヶ月 0日
0年6ヶ月 1日
0年5ヶ月30日
0年6ヶ月 0日

0年6ヶ月 0日
0年6ヶ月 1日
0年6ヶ月 0日
0年6ヶ月 1日
0年5ヶ月30日
0年6ヶ月 0日
  綺麗に [0.5] という結果が出るように閏年(2000年:年間日数=366日)を例にします

 どうでしょうか。YEARFRACによる「0.5」と、暦に従って求めた「丁度6ヶ月」とは、1日ほど前後し
てしまいますね。つまり、「0.5」とは「暦に従って、丁度6ヶ月」を意味するものではないということで
す。単に年間日数である365(366)の半分の日数位置(182 or 183)である事を指しているだけです。
暦には大小閏がありますから、「丁度6ヶ月」といっても、その日数は開始日によって異なります。

  この「基準:1」の挙動を詳しく調べてみたところ、その計算仕様は非常にいい加減なものである事
が判明しました(MSもバグであると認めています)。この「基準:1」を使って年齢などを計算する事は
非常に危険です。尚、日本での一般的な年比率の計算方式は【抽象的2月29日説】というものです。


【 Excel/DAYS360 関数の仕様について 】
  Excel のDAYS360やYEARFRACでは、年間360日の計算方式としてNASD方式/ヨーロッパ方式
という2種類のカウント方法を持っていますが、その違いがヘルプの説明だけでは判り難いと思います
ので若干補足します。この関数の基本は
      日数 = 360*{ 年(終了日) - 年(開始日) } + 30*{ 月(終了日) - 月(開始日) } + { 日(終了日) - 日(開始日) }
という式です。

  但し、この式に当て嵌める前に『月末日などの条件による日付の調整』が行なわれます。日数のカウント
方法は、この『調整の仕方』という内容で記載されています。

  尚、調整方法の説明の中で、
      終了日の31日は、31日のままとする ← 同義 → 終了日の31日を、翌月1日とする
という補足をしてありますが、これは下記の2式が等しい事から理解できるでしょう。
      31日のまま : 30*{ 月(終了日) - 月(開始日) } + { 31 - 日(開始日) }
      翌月 1日   : 30*{ 月(終了日) + 1 - 月(開始日) } + { 1 - 日(開始日) }

[ この場所へのリンク ]
【NASD方式】
      ≪ ヘルプの記載 ≫    ( Excel2007 では何故か説明が変わりました )
            開始日 が、ある月の 31 日になる場合、同じ月の 30 日として計算が行われます。終了日 が、ある月
            の 31 日になる場合は、開始日 が 30 日でない限り、その翌月の 1 日として計算が行われます。2 月
            の 28 日と 29 日は、いずれも 2 月 30 日と見なされます。
            この関数は、NASD compliant (National Association of Securities Dealers) です。つまり、開始日 が
            ある月の 31 日になる場合、同じ月の 30 日として計算が行われます。終了日 がある月の 31 日になる
            場合は、開始日 が 30 日でない限り、その翌月の 1 日として計算が行われます。2 月の 28 日と 29 日
            は、いずれも 2 月 30 日と見なされます。

    (a) 開始日が月末日の場合には、その開始日は[30日扱い]です。即ち、
            ・ 31日 は[30日扱い]
            ・ 2000/2/28(閏年) は28日のまま(≠月末)
                  (3/1までの日数は、2/29 (2/30) 3/1 と数えて3日間)
            ・ 2000/2/29,2001/2/28(平年) は[30日扱い]
                  (3/1までの日数は30(月末)の翌日から数えるので、3/1 のみの1日間)

    (b) 終了日が『31日』の場合は、その終了日は[翌1日扱い] です。即ち、
            ・ [〜3/31]の場合は[3月31日]という日付をカウントに加えるのと同じ効果になります
            ・ [〜4/ 1]の場合には[3月31日]という日付はカウントに加えません
          ただし、開始日が『30/31日』の場合には終了日『31日』は[30日扱い]です。
      終了日で、2000/2/29(閏年の月末)は29日、2001/2/28(平年の月末)は28日のままです。

[ この場所へのリンク ]
  (補足)  この、「終了日が2月末日は、そのまま」 というのは、ヘルプには記載されていませんが、
    DAYS360関数の実際の動作( 2006/2/28 〜 2006/2/28 → -2 等 ) を調べたところ、そのよう
    になっています。終了日はそのままで、開始日だけが30日に置き換わる為に [ 28 - 30 = -2 ]
    という計算となります。

     後述の解説にあるように、本来のNASD方式は SIA で定めている 30/360(SIA) という算出方法
    を採用しており、2月末日については
        a) 開始日の2月末日(平年は28日、閏年は29日)は 30日扱いとする
        b) 開始日/終了日ともに2月末日の場合には、終了日を30日扱いとする
    という処理を行ないます。しかし、DAYS360(NASD)では b) の処理が抜けている為に [−2 ] という
    結果が出てしまいます。尚、上記 b) の処理を除いた算出方法というものもあり、 30/360(PSA) と
    呼ばれていますが、NASD方式はPSAではありません。SIA準拠と定められています。

    MSは、この件(上記 b の処理が抜けて NASD準拠 即ち SIA準拠 になっていないこと)を
    Excel の不具合であると認めました (2006/6/24) 。

    Excel のDAYS360(NASD)で、30/360(SIA)方式の計算(上記の例で、-2 ではなく 0 を返す)を
    実現するには、ほんの少しアレンジすれば出来ます。

    上記のように、PSAでは[ -2 ] というのが目立ってしまいますが、開始日=終了日での日数計算が
    あまり無い事を考えれば、SIA と PSA 両者の違いとは、丁度1年間になる2月末日同士の計算
    (2004/2/29〜2005/2/28 等)で、
        SIA : 平/閏に係わり無く常に 360
        PSA : 358 (平→平,閏→平) or 359 (平→閏)
    という日数の違いにあると見た方が的確かも知れません。
 
   
  [ この場所へのリンク ]
 --- Microsoft からの回答 ---
    2006/6/24
  開始日、終了日ともに 2 月の最終日が指定された場合、SIA Standard に準拠した NASD 方式は
  終了日を 2 月 30 日に変換されなければなりませんが、DAYS360 関数は終了日を 2 月 30 日に
  変換させておりません。この動作は、DAYS360 の不具合であることが判明いたしました。

  Excel の NASD 方式は SIA Standard に準拠した仕様となっておりますが、DAYS360 、および
  YEARFRAC 関数にはそれぞれに以下のような問題がございます。
      ・ DASY360 (Excel の全てのバージョン)
                開始日、終了日ともに [2 月の最終日]が指定された場合、終了日が 2 月 30 日に
                変換されない。
      ・ YEARFRAC (Excel 2000 以降のバージョン)
                終了日が [ある月の 31 日]で開始日が [2 月の最終日]に指定されている場合、開始日を
                2 月 30 日と見なさないため、終了日が翌月の 1 日として計算される。

   
  [ この場所へのリンク ]
 --- Excel2007 のヘルプでは NASD の説明が何故か変わりました ---

  https://support.office.com/ja-JP/article/DAYS360
  a) 開始日が、ある月の最終日になる場合、同じ月の 30 日として計算が行われます。
  b) 終了日が、ある月の最終日になる場合、開始日が 同じ月の 30 日よりも前になる状況では、
     翌月の 1 日として計算が行われます。それ以外の場合、終了日は、同じ月の 30 日として
     計算が行われます。

  https://support.office.com/en-US/article/DAYS360
  a) If the starting date is the last day of a month, it becomes equal to the 30th of the
      same month.
  b) If the ending date is the last day of a month and the starting date is earlier than
     the 30th of a month, the ending date becomes equal to the 1st of the next month;
     otherwise the ending date becomes equal to the 30th of the same month.

  (1) 下線部の字消し部分は誤訳でしょう。英語版には、そのようには書いていません。
  (2) 以前は "31日" と書いてあったのが "月の最終日" という表現に変わりました。この表現では、
      小の月の 30日・2月末日(28 or 29) も含まれます。
  (3) SIA では開始日を 「31日・30日・2月末日を 30日 として計算」 する仕様ですから a) 項の
      表現でも合っています。
  (4) b) 項は "月の最終日" という表現で 大/小/2月の月末を全て含んでしまうので、開始日が
      30日より前か以降かによって終了日を
          ・ 大の月の月末(31日) ⇒ 翌月の 1日で計算( ○ )  or  30日で計算( ○ )
          ・ 小の月の月末(30日) ⇒ 翌月の 1日で計算( × )  or  30日で計算( ○ 、要はそのまま )
          ・ 2月月末(28 or 29日) ⇒ 翌月の 1日で計算( × ) or  30日で計算( △ )
      とする事になります(△:開始日が2月末日なら○、他なら×)。

  cf. 正しい SIA 仕様



[ この場所へのリンク ]
【ヨーロッパ方式】
      ≪ヘルプの記載≫
            開始日 または 終了日 が、ある月の 31 日になる場合、同じ月の 30 日として計算が行われます。

      開始日/終了日ともに『31日』は[30日扱い] です。即ち、
          ・ [〜3/31]でも[〜4/1]でも、[3月31日]という日付はカウントに加えません
      開始/終了日ともに、2000/2/29は29日、2001/2/28は28日のままです。
          ・ 開始日が2001/2/28の場合、3/1までの日数は、(2/29)(2/30) 3/1 と数えて3日間です。

    (補足)
    この、「開始日/終了日ともに 2月末日は、そのまま」 というのは、ヘルプには記載されていま
    せんが、DAYS360関数の実際の動作を調べたところ、そのようになっています。尚、平年/閏年
    間の計算をすると下記のようになります。
        2003/2/28 〜 2004/2/29 → 361
        2004/2/29 〜 2005/2/28 → 359
        2005/2/28 〜 2006/2/28 → 360
        2003/2/28 〜 2003/2/28 → 0
        2004/2/29 〜 2004/2/29 → 0
        2003/2/28 〜 2007/2/28 → 1440
        2004/2/29 〜 2008/2/29 → 1440
    単に ヨーロッパ方式と言っても、実は [30E/360] [30E+/360] と 表現される2種類の算出法が
    あり、DAYS360 関数では [30E/360] 方式を採用しているようです。これらの規定では、開始日
    /終了日ともに 「2月末日はそのまま」 という処理を行なっています。両者の違いは
       30E/360    : 終了日が 31日の場合、終了日を 30日として扱う
       30E+/360  : 終了日が 31日の場合、終了日を 翌月の 1日として扱う
    という点です。これは「最後の 31日をカウントするかしないか」 という事です。実際の例としては
        2003/2/28 〜 2003/3/31  : 32日 (30E/360) , 33日 (30E+/360)
        2003/4/30 〜 2003/5/31  : 30日 (30E/360) , 31日 (30E+/360)
    という結果になります。
 





[ この場所へのリンク ]
( Note )  MS-KB にあるDAYS360関連ドキュメント
  DAYS360のMS-KB ドキュメントを検索すると下記の2つが見つかります。

  DAYS360関数では「NASD と ヨーロッパ方式」という2種類の計算方法を提供していますが、そも
そも、『30日/月&360日/年』とする日数計算方法には、それ以外にも多くの種類があります

  Excel のDAYS360関数では、その内の2つを「NASD方式 / ヨーロッパ方式」として提供している
に過ぎません。

  それであれば、その2つ以外の方式を使っている業務に於いてDAYS360関数を使えば、得られる
結果が「期待するものとは異なる」というケースが当然出て来る訳です。

  そこで、私のkt関数アドイン/ktPeriodYMDの解説でも言っている事ですが
      【その業務で行なう計算方法に合っているかどうかを調べて、合っている場合にのみ使う】
という接し方が大切になってきます。

    [ An unexpected value is returned when you use the DAYS360 function in Microsoft Excel ]
    https://support.microsoft.com/en-us/kb/916004  ( by Internet Archive )
    https://support.microsoft.com/ja-jp/kb/916004 (日本語)  ( リンク切れ )

    【要約】
        DAYS360にNASD方式を指定した場合、開始日が2月末日(平年28日、閏年29日)であり、
        終了日がそれに対応して28日または29日の場合に正しく30日間という結果が返らない。
            =DAYS360("2006/2/28", "2006/3/28", FALSE)  →  28
            =DAYS360("2008/2/29", "2008/3/29", FALSE)  →  29

        これを回避するには、[方式]の引数に TRUE (ヨーロッパ方式) を指定する。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  ( 補足 )
    このケースで 30日間になる計算方式としては、後述のように、30/360(ISDA or MSRB) , 30E/360 ,
  30E+/360 の3つがあります。Excel のDAYS360 (ヨーロッパ方式) は 30E/360 に当たります。

   この出題の意味合いとしては3つの背景が考えられます。
        (1) NASD方式を考えているが、[2006/2/27〜2006/3/27] [2008/2/28〜2008/3/28] 又は
             [2006/1/28〜2006/2/28] [2008/1/29〜2008/2/29] が30日間という結果になるのだから、
             上記のケースも 「"同日" 間で30日間になる筈」 という考え方をしている。

        (2) ヨーロッパ方式(30E/360)のつもりでいたが、引数に誤って FALSE を指定している。

        (3) 30/360(ISDA or MSRB) or 30E+/360 の計算方式を採用する式を作ろうとしている。

  (1) の場合は 『日数計算の定義を勘違いして、30日間になると思い込んでいる』 という事になります。
  Excel/DAYS360(NASD)の計算方式である30/360(PSA)も、真のNASD計算方式である30/360(SIA)
  も、上記のケースでは30日間にはなりません。上記の結果の通りになります。

  (2) の場合は、引数指定の間違いですから、回答のように TRUE を指定するように変えれば済みます。

  (3) の場合は、計算方式が合っていませんから、『Excel のDAYS360 をそのまま使用する』 という事自体
  そのものが 間違っていると言えます。

    DAYS360 (NASD or ヨーロッパ) に幾つかの条件を プラスα すれば、その業務に合うというので
  あれば、式を工夫する事で対処する事も可能でしょう。例えば、DAYS360(NASD)で盛られていな
  い 『開始日/終了日ともに2月末日の場合は、終了日を30日に置き換える』 という条件を加える、
  即ち、30/360(SIA) 方式を実現する場合は以下の式で対処できます。

[ この場所へのリンク ]
    【 Excel/DAYS360 で 30/360(SIA) 方式の計算を行なう
      =IF(AND(TEXT(開始日+1, "MMDD")="0301" , TEXT(終了日+1, "MMDD")="0301") ,
            360*(YEAR(終了日)-YEAR(開始日)) ,
            DAYS360(開始日, 終了日, FALSE))
        2月月末同士の計算のみを場合分けして、「年」の引算に 360 を掛ける。
              [y1/2/30 〜 y2/2/30] という同日の期間なので 「丸N年丁度」 になる。

 
 
    [ DAYS360 Function Produces Different Values Depending on the Version of Excel ]
    https://support.microsoft.com/en-us/kb/235575    ( リンク切れ )
    https://support.microsoft.com/ja-jp/kb/235575 (日本語)    ( リンク切れ )

    【要約】
          DAYS360関数は Excel4.0 の頃より提供されていますが、Excel4.0 では[ヨーロッパ方式]の
        算出のみであり、その頃のDAYS360には[方式]引数がありませんでした。Excle5.0 より[方式]
        引数が追加され、NASD方式とヨーロッパ方式を選択できるようになりました。只、NASD方式
        が 『既定』 となっている為、[方式]引数を省略するとNASD方式による算出が行なわれます。
          Excel4.0 のままに、Excel4.0 の時と同じ結果を期待して、DAYS360に開始日と終了日のみ
        を指定していると、既定のNASD方式になってしまう為、期待通りの結果(ヨーロッパ方式の結
        果)が得られません。
          これを回避して、Excel4.0 の時と同じ結果を得るには、[方式]引数に明示的に TRUE を指定
        する必要があります。

        -- Excel4.0 --
          =DAYS360("1993/2/28", "1993/3/1")  → 3
          =DAYS360("1996/2/29", "1996/3/1") → 2

        -- Excel5.0 以降 (Excel97,2000,2002,2003) --
          =DAYS360("1993/2/28", "1993/3/1")  → 1    (開始日/終了日のみ指定、FALSE は省略)
          =DAYS360("1996/2/29", "1996/3/1") → 1    (開始日/終了日のみ指定、FALSE は省略)
          =DAYS360("1993/2/28", "1993/3/1", TRUE)  → 3
          =DAYS360("1996/2/29", "1996/3/1", TRUE) → 2
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  ( 補足 )
    こちらは、バージョンアップに伴う 『機能追加とインターフェース変更』 によって、「以前 (Excel4.0)
  と同じ書き方のままでは、以前 (Excel4.0) の時と同じ結果は得られない」 とする【注意事項】の意味
  合い、ということで間違いないようです。
 
 



[ この場所へのリンク ]
【 30日/月 & 360日/年 という日数計算方法とは 】

  最初にお断りしておきますが、残念ながら、以下にまとめた内容は「一次ソース」の情報に基づく
ものではありません。幾つかの金融系ソフトの解説から日数計算に関して書かれている内容(二次
ソース)を見比べて整理したものです(Excel で言えば DAY360のヘルプ)。

  本来なら、日数計算の定義を定めた機関のドキュメント(一次ソース)があれば良いのですが、中々
探し出せません。そこで、金融系ソフトが提供している「幾つかの日数計算方式」に付随した解説の
「この機関が定めた日数計算は、こういう内容」といった情報(二次ソース)から整理しました。

  一番確実なのは、NASDの定義文書の中で、このパターン(開始日が2月28(29)日)の場合に、
どういう日数になるのかという記述を探してみる事ですが、今のところ見つけられていません。とりあ
えず2月に言及しているものとしては下記が見つかりました。
      Rule 11620. Computation of Interest
        http://finra.complinet.com/en/display/display_main.html?rbid=2403&element_id=3816  ( by Internet Archive )

    From 1st to 28th of February to be figured as 27 days;
    From the 23rd of February to the 3rd of March is to be figured as 10 days;
    From the 15th of May to the 6th of June is to be figured as 21 days.
 
これは、「2月も30日間/月と数える」という意味合いの例示ですが、月の中日からの期間ですので、
ここからは、2月の28(29)日の時にはどうかという判断は汲み取れません。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  先ず、『30日/月 & 360日/年』方式での「開始日〜終了日」間の日数は以下の式で計算されます。
      日数 = 360*{ 年(終了日) - 年(開始日) } + 30*{ 月(終了日) - 月(開始日) } + { 日(終了日) - 日(開始日) }

但し、この式に当て嵌める前に開始日/終了日に対して、『月末日などの条件による日付の調整』が
行なわれます。日数のカウント方法は、この『調整の仕方』という内容で記載されています。

調整方法の説明の中で、
      終了日の31日は、31日のままとする ← 同義 → 終了日の31日を、翌月1日とする
という補足をしてありますが、これは下記の2式が等しい事から理解できるでしょう。
      31日のまま : 30*{ 月(終了日) - 月(開始日) } + { 31 - 日(開始日) }
      翌月 1日   : 30*{ 月(終了日) + 1 - 月(開始日) } + { 1 - 日(開始日) }

  尚、計算方法を定義した機関によって日付の調整の仕方が異なり、それが、この日数計算方法の
種類になります。幾つかの機関の略号が出て来ますが、フルスペルは下記になります。
      BMA ( Bond Market Association )
      PSA ( Public Securities Association ) : BMAの前身(旧名称)
      ISDA ( International Swaps and Derivatives Association )
      SIA ( Securities Industry Association )
      NASD ( National Association of Securities Dealers )
      U.S.Muni ( U.S. Municipal Bond market )
      MSRB ( Municipal Securities Rulemaking Board )


  前記のDAYS360(NASD)解説のところで、[ -2 ] が出る原因として触れた
     「開始日/終了日ともに 2月末日の場合、終了日を 30日とする」
という条件について見てみると、
   (a) Wiki に書かれている解説によれば、30/360(PSA) の定義に含まれる
   (b) FinCAD および WWWFinance に書かれている解説によれば、30/360(PSA)の定義には、
        その条件が含まれていません。加えて、FinCAD に書かれている解説によれば、上記条件
        も含むのは、30/360(SIA) 方式という事になっています。
この場合、多数決による見方はあまり薦められるものではないとは思いますが、「PSAには上記条
件は含まれない」とする方が正しいように思えます。また、Entisoft Tool に書かれている解説によ
れば、
    (c) NASDが使っている定義はSIAのもの
となっています。そして、
    (d) Entisoft Tool が SIA準拠で計算したものと、Excel/DAYS360(NASD)と同じ
        方式で計算したものでは違う結果になるケースがある(即ち [ -2 ] のケース)。
という風に書かれています。また、別の Wiki 記事にも
    (e) NASDが使っている定義はSIAのもの
    (f) Excel がNASD方式と呼んでいる計算方法は SIA準拠ではない
と書かれています。ここから
        Excel のDAYS360(NASD) のヘルプには、『NASD compliant (準拠)』と書かれて
      はいるが、NASDが採用している 30/360(SIA) とは一致しない部分がある。その部分
      (即ち、[ -2 ] になる原因の「開始日/終了日ともに2月末日の場合は終了日を30日
      にする」)を除いた規定で作られている計算方式は 30/360(PSA) である。
        結論として、Excel/DAYS360(NASD) はNASD準拠とされてはいるが、実際の所は、
      NASDが採用している 30/360(SIA) とは若干異なる 30/360(PSA) に基づいて設計
      されたものである。

という推論を立てる事が可能なように思えます。DAYS360(NASD)で正しくNASD準拠の計算を行な
うには前述の式を使って下さい。
    MS はDAYS360(NASD)の計算方法が SIAではなくPSAになっている件を
    Excel の不具合であると認めました (2006/6/24)。


  尚、上記のように、30/360(PSA)では[ -2 ] というのが目立ってしまいますが、開始日=終了日
での日数計算があまり無い事を考えれば、30/360(SIA) と 30/360(PSA) 両者の違いとは、丁度
1年間になる2月末日同士の計算(2004/2/29〜2005/2/28 等)で、
        SIA : 平/閏に係わり無く常に 360
        PSA : 358 (平→平,閏→平) or 359 (平→閏)
という日数の違いにあると見た方が的確かも知れません。

[ この場所へのリンク ]
  ところで、YEARFRAC関数にもNASD方式という指定がありますが、こちらは以下の調査の結果
DAYS360(NASD)とは異なり、30/360(SIA)で計算されているようです。
      [ 左: DAYS360(A1,B1,FALSE)/360 ] と [ 右: YEARFRAC(A1,B1,0) ] の比較
            2004/2/29 〜 2008/2/29      3.9972      4.0000
            2005/2/28 〜 2008/2/29      2.9972      3.0000
            2005/2/28 〜 2009/2/28      3.9944      4.0000
この結果は、後述の ktDAYS360 関数で求めた 30/360(PSA) および 30/360(SIA) の日数を
360で割った値に一致します。

(注) YEARFRAC関数では、Excel97 と Excel2000以降の間で一部計算結果が異なります
   以下のように[2月末日〜大の月の31日]というパターンで違いが出て来ます。
            2002/2/28 〜 2002/12/30  (97) 0.83333     (2000以降) 0.83333
            2002/2/28 〜 2002/12/31  (97) 0.83333     (2000以降) 0.83611
            2004/2/29 〜 2004/12/30  (97) 0.83333     (2000以降) 0.83333
            2004/2/29 〜 2004/12/31  (97) 0.83333     (2000以降) 0.83611
            2004/2/29 〜 2005/ 1/30   (97) 0.91667     (2000以降) 0.91667
            2004/2/29 〜 2005/ 1/31   (97) 0.91667     (2000以降) 0.91944
    Excel97では、以下に示すSIA定義そのままに実装されていたものが、何故かExcel2000の
    時点で、下記SIA定義の太字下線部分(開始日=30,31日 or 2月末日の意)から2月末日
    の条件が漏れて『開始日=30 or 31日』という風になってしまったものと思われます。
           30/360 (SIA)
              (2) 開始日が31日または2月末日の場合、開始日を30日に置き換える。
              (3) 上記(2)適用後の開始日が30日で且つ終了日が31日の場合、終了日を30日に置き換える。
                  (つまり、開始日が29日以前ならば、最終日は31日のまま。これは、翌月1日に置換と同義)。

      この為、開始日が2月末日の場合に(3)が適用されず(括弧内の条件の方になる)、終了日
    の31日がカウントに加えられる事で1日分多くなり、上記の違いになったものと思われます。
     (300÷360=0.83333 , 301÷360=0.83611 , 330÷360=0.91667 , 331÷360=0.91944)
    尚、DAYS360(NASD)では、何れのバージョンであっても上記のケースでは 300 及び 330
    を返し、「終了日の31日」はカウントには加えられません。
      MSは、このバージョン間で計算が異なる件をExcel の不具合であると認めました (2006/6/24)。


  以上の事から、Excel で MSがNASD方式と称する計算方式には、同じNASDを冠してい
ても、実際のところ3種類の計算方式が存在している事が判ります。
    a) DAYS360 の NASD方式(全バージョン)
    b) YEARFRAC の NASD方式 (Excel97)
    c) YEARFRAC の NASD方式 (Excel2000 以降)
この内、胸を張って本当に「NASD (SIA)準拠」と言えるのは b) だけのようです。
a) と c) について、MSはExcel の不具合であると認めました(2006/6/24)。


  以降のドキュメントの原文は英語ですが、訳したものを掲載します。
  原文を確認したい方はリンク先を参照して下さい。 
  [ この場所へのリンク ]
  Wikipedia/Day count convention
  https://en.wikipedia.org/wiki/Act/360#30.2F360

  Date-a = Date1 - 1day, if dd(date1) = 31
                Date1          , otherwise
  Date-b = Date2 - 1day, if dd(Date2) = 31 and dd(Date1) ≧ 30
                Date2 + 1day, if dd(Date2) = 31 and dd(Date1) < 30
                Date2          , otherwise
  上式を文章で表現すると
      ・ 開始日が 31日の場合は30日とします。
      ・ 終了日が 31日の場合、開始日が 30/31日ならば 30日、
                                          開始日が 29日以前ならば 翌月の1日とします。
  種類
 ※ 30E/360   : 終了日が31日は30日とします。
 ※ 30E+/360 : 終了日が31日は翌月の1日とします。
 ※ 30/360 ISDA : 上記で示した定義です。
 ※ 月末の取り決め (PSA) :
          この取り決めは、30/360 または、その類型のルールに付け加える事ができます。
          開始日が2月末日(平年は28日、閏年は29日)の場合は30日とします。また、開始日
          /終了日が共に2月末日の場合は、終了日を30日とします。
 
 
  [ この場所へのリンク ]
  Wikipedia/360 day calendar
  https://en.wikipedia.org/wiki/360_day_calendar

  この Wikipedia の記事には、ハッキリ と 「NASD は 以下の SIA 文書に定義されている計算方法を
  採用している」 と書かれています。
  加えて、Excel の NASD方式というものが 「SIA 準拠ではない」 とも述べています。

    The US/NASD method is defined in:
        Securities Industry Association, Standard Securities Calculation Methods:
            Fixed Income Securities Formulas for Analytic Measures, Vol. 2, Spring 1995.

    Reportedly, Excel's US/NASD method is not SIA-compliant.
    Other methods include the ISDA 360-day calendar, and the PSA 360-day calendar.
 
 
  [ この場所へのリンク ]
  FinCAD    Day Count Conventions and Accrual Factors
  http://www.fincad.com/support/developerfunc/mathref/Daycount.htm  ( by Internet Archive )

  30/360 (ISDA) (same as U.S. Muni 30/360  即ち 30/360(MSRB ) )
    (1) 開始日が31日の場合、30日に置き換える。
    (2) 上記(1)適用後の開始日が30日で且つ最終日が31日の場合、最終日を30日に置き換える。
        (つまり、開始日が29日以前ならば、最終日は31日のまま。これは、翌月1日に置換と同義)。

  30/360 (SIA)
    (1) 期間の最終日が2月末日で、期間の開始日も2月末日の場合、終了日を30日に置き換える。
    (2) 開始日が31日または2月末日の場合、開始日を30日に置き換える。
    (3) 上記(2)適用後の開始日が30日で且つ終了日が31日の場合、終了日を30日に置き換える。
        (つまり、開始日が29日以前ならば、最終日は31日のまま。これは、翌月1日に置換と同義)。

  30/360 (BMA) 30/360(PSA) とも言う (PSA は BMA の前身 )
    (1) 開始日が31日または2月末日の場合、30日に置き換えます。
    (2) (1)を適用した後の開始日が30日で且つ終了日が31日の場合は、終了日を30日に置き換えます。
        (つまり、開始日が29日以前ならば、最終日は31日のまま。これは、翌月1日に置換と同義)。

  30E/360 (30/360 ISMA)
    (1) 開始日が31日の場合、30日に置き換える。
        終了日が31日の場合、30日に置き換える。
    (2) 終了日が2月末日の場合、2月を30日/月には拡張しない。
        より正確に言えば、2月の実日数が使用されます。

  30E+/360
    (1) 開始日が31日の場合、30日に置き換える。
    (2) 終了日が31日の場合、翌月の1日に置き換える (これは、31日のままにする事と同義)。
 
 
  [ この場所へのリンク ]
  WWWFinance    Day Counting for Bonds
  https://people.duke.edu/~charvey/Classes/ba350_1997/pricing/daycount.htm

  Public Securities Association (PSA) は、2日付間の日数を計算する為のルールを以下のように
  定めています。
    1. If D1 is 31, change D1 to 30.
    2. if D2 is 31 and D1 is 30 or 31, then change D2 to 30.
    3. If M1 is 2, and D1 is 28 (in a non-leap year) or 29, then change D1 to 30.
    Then the number of days, N is: N = 360(Y2 - Y1) + 30(M2 - M1) + (D2 - D1)
 上式を文章で表現すると
    1.開始日が 31日の場合、30日に置き換える。
    2.終了日が 31日で、開始日が30/31日の場合、終了日を30日に置き換える。
    3.開始日が 2/28(平年) または 2/29(閏年)の場合、開始日を30日に置き換える。
 
 
  [ この場所へのリンク ]
  Entisoft Tools 2.0 Object Library    Days 360 Function Math Financial Class
  http://www.entisoft.com/ESTools/MathFinancial_Days360.HTML

  vEuroMethod:
      ヨーロッパ方式の30/360日数計算の場合はTrue、US NASD方式の30/360日数計算
      の場合はFalse を指定。既定はFalse(US NASD方式の30/360日数計算になります)。
  vExcelVersion:
      ExcelのDAYS360関数と完全に同じ結果を得る場合は True を指定します。
      SIA (Securities Industy Association)で定義されている30/360方式を使う場合は
      False を指定します(US NASD の30/360日数計算はSIA の定義を使っています)。

  この関数は[vExcelVersion=True]の場合、ExcelのDAYS360と完全に同じ結果を返します。
  [vExcelVersion=False]の場合、この関数とDAYS360は以下の日付で異なる結果を返します。
                                              (False)  (True)
     1991/2/28 〜 1991/2/28         0        -2
     1991/2/28 〜 1992/2/29      360      359
     1992/2/29 〜 1992/2/29          0        -1
     1992/2/29 〜 1993/2/28      360      358
 
 
  [ この場所へのリンク ]
  Municipal Securities Rulemaking Board / Rule G-33 (e)
  http://www.msrb.org/Rules-and-Interpretations/MSRB-Rules/General/Rule-G-33.aspx#_e  ( by Internet Archive )

  (e) Day Counting.
      For purposes of this formula, if the symbol "D2" has a value of "31," and the symbol "D1"
      has a value of "30" or "31," the value of the symbol "D2" shall be changed to "30." If the
      symbol "D1" has a value of "31," the value of the symbol "D1" shall be changed to "30."

      開始日が30/31日で終了日が31日の場合は、終了日を30日にする。
      (つまり、開始日が29日以前ならば、最終日は31日のまま。これは、翌月1日に置換と同義)。
      開始日が31日の場合は、開始日を30日にする。
 




[ この場所へのリンク ]
【 30/360 日数計算マクロ 】

  『30日/月 & 360日/年』方式での「開始日〜終了日」間の日数は以下の式で計算されます。
      日数 = 360*{ 年(終了日) - 年(開始日) } + 30*{ 月(終了日) - 月(開始日) } + { 日(終了日) - 日(開始日) }

但し、この式に当て嵌める前に開始日/終了日に対して、『月末日などの条件による日付の調整』
が行なわれます。

調整方法の説明の中で、
      終了日の31日は、31日のままとする ← 同義 → 終了日の31日を、翌月1日とする
という補足をしてありますが、これは下記の2式が等しい事から理解できるでしょう。
      31日のまま : 30*{ 月(終了日) - 月(開始日) } + { 31 - 日(開始日) }
      翌月 1日   : 30*{ 月(終了日) + 1 - 月(開始日) } + { 1 - 日(開始日) }

上記 FinCAD に書かれている定義を基にして、Excel/VBA 並びに OOoBasic で関数を作成す
ると以下のマクロになります。

JavaScriptによる日数計算日付をYYYY/M/Dで入力(日付ボタンで暦表示)。
  から の日数を
        実日数(暦通りの日数)  
        30/360(SIA)           (NASD の本当の計算方式)
        30/360(PSA or BMA)     (Excel/DAYS360 で NASD方式 を選択した場合)
        30/360(ISDA or MSRB)  
        30E/360               (Excel/DAYS360 で ヨーロッパ方式 を選択した場合)
        30E+/360              

    【 VBA/OOoBasic マクロ 】  (注) OOo Basic の場合、修正が必要(末尾参照)
    DAYS360モード(日数計算) と YEARFRACモード(年比率計算)が利用できます。

  新元号 [ 令和 ] 対応のアップデートが施されている環境では、下記 マクロコード のままで
      引数 ( Satrt_Date / End_Date ) に "令和1年5月1日" 等の日付文字列 を指定可能です。
      未アップデート環境で 「令和日付」 に対応する為の修正方法は後述。


  Public Function ktDAYS360(ByVal Start_Date As Date, _
                            ByVal End_Date As Date, _
                            ByVal Method As Integer, _
                            Optional ByVal Fraction As Boolean = FalseAs Variant
  '[Method]
  '   0:30/360(SIA), 1:30/360(PSA or BMA), 2:30/360(ISDA or MSRB)
  '   3:30E/360, 4:30E+/360
  '  【ExcelのDAYS360は、NASD方式=30/360(PSA), ヨーロッパ方式=30E/360】
  '[Fraction]
  '   False:日数(DAYS360モード) , True:年比率(YEARFRACモード)

  Dim blnLastFeb1 As Boolean
  Dim blnLastFeb2 As Boolean
  Dim intYear1 As Integer
  Dim intYear2 As Integer
  Dim intMonth1 As Integer
  Dim intMonth2 As Integer
  Dim intDay1 As Integer
  Dim intDay2 As Integer
  Dim lngDAYS As Long

  If (Start_Date > End_Date) Then
    ktDAYS360 = CVErr(xlErrValue)
    Exit Function
  End If

  '2月末日の判定(即ち、翌日が3月1日)
  If (Format(Start_Date + 1, "mmdd") = "0301") Then
      blnLastFeb1 = True
  Else
      blnLastFeb1 = False
  End If
  If (Format(End_Date + 1, "mmdd") = "0301") Then
      blnLastFeb2 = True
  Else
      blnLastFeb2 = False
 End If

  intYear1 = Year(Start_Date)
  intMonth1 = Month(Start_Date)
  intDay1 = Day(Start_Date)

  intYear2 = Year(End_Date)
  intMonth2 = Month(End_Date)
  intDay2 = Day(End_Date)

  Select Case Method
    Case 0
  '   30/360(SIA)
  '    (1) 期間の最終日が2月末日で、期間の開始日も2月末日の場合、
  '        終了日を30日に置き換える。
  '    (2) 開始日が31日または2月末日の場合、開始日を30日に置き換える。
  '    (3) 上記(2)適用後の開始日が30日で且つ終了日が31日の場合、
  '        終了日を30日に置き換える(つまり、開始日が29日以前ならば、
  '        最終日は31日のまま。これは、翌月1日に置換と同義)。
      If (Day(Start_Date) = 31) Or (blnLastFeb1 = TrueThen
          intDay1 = 30
      Else
      End If

      If (blnLastFeb1 = TrueAnd (blnLastFeb2 = TrueThen
          intDay2 = 30
      ElseIf (intDay1 = 30) And (Day(End_Date) = 31) Then
          intDay2 = 30
      Else
      End If

    Case 1
  '   30/360(PSA or BMA)
  '    (1) 開始日が31日または2月末日の場合、30日に置き換える。
  '    (2) (1)を適用した後の開始日が30日で且つ終了日が31日の場合は、
  '        終了日を30日に置き換えます(つまり、開始日が29日以前ならば、
  '        最終日は31日のまま。これは、翌月1日に置換と同義)。
      If (Day(Start_Date) = 31) Or (blnLastFeb1 = TrueThen
          intDay1 = 30
      Else
      End If

      If (intDay1 = 30) And (Day(End_Date) = 31) Then
          intDay2 = 30
      Else
      End If

    Case 2
  '   30/360(ISDA or MSRB)
  '    (1) 開始日が31日の場合、30日に置き換える。
  '    (2) 上記(1)適用後の開始日が30日で且つ最終日が31日の場合、
  '        最終日を30日に置き換える(つまり、開始日が29日以前ならば、
  '        最終日は31日のまま。これは、翌月1日に置換と同義)。
      If (Day(Start_Date) = 31) Then
          intDay1 = 30
      Else
      End If

      If (intDay1 = 30) And (Day(End_Date) = 31) Then
          intDay2 = 30
      Else
      End If

    Case 3
  '   30E/360
  '    (1) 開始日が31日の場合、30日に置き換える。
  '    (2) 終了日が31日の場合、30日に置き換える。
      If (Day(Start_Date) = 31) Then
          intDay1 = 30
      Else
      End If

      If (Day(End_Date) = 31) Then
          intDay2 = 30
      Else
      End If

    Case 4
  '   30E+/360
  '    (1) 開始日が31日の場合、30日に置き換える。
  '    (2) 終了日が31日の場合、翌月の1日に置き換える。
  '        (これは、31日のままにする事と同義)
      If (Day(Start_Date) = 31) Then
          intDay1 = 30
      Else
      End If

    Case Else
      ktDAYS360 = CVErr(xlErrValue)
      Exit Function
  End Select

  ' 360*年がIntegerの範囲を越える可能性がある為 Long型とする(結果もLong型になる)
  lngDAYS = 360& * CLng(intYear2 - intYear1) _
            + 30 * (intMonth2 - intMonth1) _
            + (intDay2 - intDay1)

  If (Fraction = FalseThen
      ktDAYS360 = lngDAYS
  Else
      ktDAYS360 = CDbl(lngDAYS) / 360#
  End If
  End Function

  ------------------------------------------------------------
  OOo Basic の場合、以下の6点の修正が必要です。
                    Optional ByVal Fraction As Boolean = False) As Variant
                    Optional ByVal Fraction As Boolean) As Variant

  Dim
lngDAYS As Long
  If IsMissing(Fraction) Then    '←Fractionの省略時解釈を追加
      Fraction = False
  End If

  If (Start_Date > End_Date) Then
      ktDAYS360 = CVErr(xlErrValue)
      ktDAYS360 = "Err"
      Exit Function
  End If

  '2月末日の判定(即ち、翌日が3月1日)
 
If (Format(Start_Date + 1, "mmdd") = "0301") Then
  If (Month(Start_Date + 1) = 3) And (Day(Start_Date + 1) = 1) Then
      blnLastFeb1 = True
  Else
      blnLastFeb1 = False
  End If
  If (Format(End_Date + 1, "mmdd") = "0301") Then
  If (Month(End_Date + 1) = 3) And (Day(End_Date + 1) = 1) Then
      blnLastFeb2 = True
  Else
      blnLastFeb2 = False
  End If


    Case Else
      ktDAYS360 = CVErr(xlErrValue)
      ktDAYS360 = "Err"
      Exit Function
  End Select



 
[ Excel 2007 以前 ] 等、新元号[ 令和 ] 未対応の環境で 令和日付文字列を指定可能にする修正方法
    新元号対応 日付変換関数 の マクロコード [ NewEraFunction.bas ] をインポートで組み込んだ後、
    下記 赤字 部分を追加/修正してください。
  - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Public Function ktDAYS360(ByVal Start_Date As Variant, _
                          ByVal End_Date As Variant, _
                          ByVal Method As Integer, _
                          Optional ByVal Fraction As Boolean = False) As Variant
    :
Dim dtmStart_Date As Date      '日付引数の型変換(Start_Date)
Dim dtmEnd_Date As Date        '日付引数の型変換(End_Date)

Dim blnLastFeb1 As Boolean
    :
Dim lngDAYS As Long

  If EraIsDate(Start_Date) And EraIsDate(End_Date) Then
    dtmStart_Date = EraCDate(Start_Date)
    dtmEnd_Date = EraCDate(End_Date)
  Else
    ktDAYS360 = CVErr(xlErrValue)
    Exit Function
  End If


  If (dtmStart_Date > dtmEnd_Date) Then
    ktDAYS360 = CVErr(xlErrValue)
    Exit Function
  End If

( 以下、Start_Date ⇒ dtmStart_Date , End_Date ⇒ dtmEnd_Date に全て置換する )




[ この場所へのリンク ]
【 ワークシート関数 LET による 30/360 日数計算式 ( Excel 2021 以降 ) 】 ( 2023/10/19 追記 )
    30/360 基準の日数計算は単純な式なので、Excel2021より導入されたワークシート関数 [ LET ] で
    組み立てることも可能です。下記式では、A1セル:開始日、B1セル:終了日を指します。
 
  --- 30/360(SIA) ----
    (1) 期間の最終日が2月末日で、期間の開始日も2月末日の場合、
        終了日を30日に置き換える。
    (2) 開始日が31日または2月末日の場合、開始日を30日に置き換える。
    (3) 上記(2)適用後の開始日が30日で且つ終了日が31日の場合、
        終了日を30日に置き換える。(つまり、開始日が29日以前ならば、
        最終日は31日のまま。これは、翌月1日に置換と同義)

  =LET(
    LASTFEB1,(TEXT(A1+1,"MMDD")="0301"),
    LASTFEB2,(TEXT(B1+1,"MMDD")="0301"),
    YEAR1,YEAR(A1),
    MONTH1,MONTH(A1),
    DAY1W,DAY(A1),
    DAY1,IF(OR(DAY1W=31,LASTFEB1),30,DAY1W),
    YEAR2,YEAR(B1),
    MONTH2,MONTH(B1),
    DAY2W,DAY(B1),
    DAY2,IF(AND(LASTFEB1,LASTFEB2),30,IF(AND(DAY1=30,DAY2W=31),30,DAY2W)),
    360*(YEAR2-YEAR1)+30*(MONTH2-MONTH1)+(DAY2-DAY1)
  )


  --- 30/360(PSA or BMA) ---  Excel DAYS360 ( NASD方式 )
    (1) 開始日が31日または2月末日の場合、30日に置き換える。
    (2) (1)を適用した後の開始日が30日で且つ終了日が31日の場合は、
        終了日を30日に置き換えます。(つまり、開始日が29日以前ならば、
        最終日は31日のまま。これは、翌月1日に置換と同義)
    (補) NASD の本来の仕様は SIA 方式。DAYS360(NASD) が PSA 方式なのは Excel の不具合です。

  =LET(
    LASTFEB1,(TEXT(A1+1,"MMDD")="0301"),
    YEAR1,YEAR(A1),
    MONTH1,MONTH(A1),
    DAY1W,DAY(A1),
    DAY1,IF(OR(DAY1W=31,LASTFEB1),30,DAY1W),
    YEAR2,YEAR(B1),
    MONTH2,MONTH(B1),
    DAY2W,DAY(B1),
    DAY2,IF(AND(DAY1=30,DAY2W=31),30,DAY2W),
    360*(YEAR2-YEAR1)+30*(MONTH2-MONTH1)+(DAY2-DAY1)
  )


  --- 30/360(ISDA or MSRB) ---
    (1) 開始日が31日の場合、30日に置き換える。
    (2) 上記(1)適用後の開始日が30日で且つ最終日が31日の場合、
        最終日を30日に置き換える。(つまり、開始日が29日以前ならば、
        最終日は31日のまま。これは、翌月1日に置換と同義)

  =LET(
    YEAR1,YEAR(A1),
    MONTH1,MONTH(A1),
    DAY1W,DAY(A1),
    DAY1,IF(DAY1W=31,30,DAY1W),
    YEAR2,YEAR(B1),
    MONTH2,MONTH(B1),
    DAY2W,DAY(B1),
    DAY2,IF(AND(DAY1=30,DAY2W=31),30,DAY2W),
    360*(YEAR2-YEAR1)+30*(MONTH2-MONTH1)+(DAY2-DAY1)
  )


  --- 30E/360 ---    Excel DAYS360 ( ヨーロッパ方式 )
    (1) 開始日が31日の場合、30日に置き換える。
    (2) 終了日が31日の場合、30日に置き換える。

  =LET(
    YEAR1,YEAR(A1),
    MONTH1,MONTH(A1),
    DAY1W,DAY(A1),
    DAY1,IF(DAY1W=31,30,DAY1W),
    YEAR2,YEAR(B1),
    MONTH2,MONTH(B1),
    DAY2W,DAY(B1),
    DAY2,IF(DAY2W=31,30,DAY2W),
    360*(YEAR2-YEAR1)+30*(MONTH2-MONTH1)+(DAY2-DAY1)
  )


  --- 30E+/360 ---
    (1) 開始日が31日の場合、30日に置き換える。
    (2) 終了日が31日の場合、翌月の1日に置き換える。
        (これは、31日のままにする事と同義)

  =LET(
    YEAR1,YEAR(A1),
    MONTH1,MONTH(A1),
    DAY1W,DAY(A1),
    DAY1,IF(DAY1W=31,30,DAY1W),
    YEAR2,YEAR(B1),
    MONTH2,MONTH(B1),
    DAY2,DAY(B1),
    360*(YEAR2-YEAR1)+30*(MONTH2-MONTH1)+(DAY2-DAY1)
  )



[ この場所へのリンク ]
【 OpenOffice.org Calc / Google SpreadSheet 】  (2010/5/30 追記)

OpenOffice.org Calc と Google SpreadSheet の DAYS360/YEARFRAC 関数の計算方式は
以下のようになっています。

(注) 正しいNASD方式は 30/360(SIA)です。
      SIA と PSA 両者の違いとは、丁度1年間になる2月末日同士の計算(2004/2/29〜2005/2/28 等)で、
      [ SIA : 平/閏に係わり無く常に 360 ]  [ PSA : 358 (平→平,閏→平) or 359 (平→閏) ]
      2004/02/29 - 2005/02/28 = 358 (PSA) , 360 (SIA)
      2002/02/28 - 2003/02/28 = 358 (PSA) , 360 (SIA)
      2003/02/28 - 2004/02/29 = 359 (PSA) , 360 (SIA)

〜 OpenOffice.org Calc 〜
  DAYS360 ( NASD )       …… 30/360(PSA)
  YEARFRAC ( NASD )    …… 30/360(PSA)
  YEARFRAC ( Act/Act ) …… 独自方式 ( AFB 方式が近い?) , 詳細は こちら を参照

  仕様では NASD方式を SIA で定義していますが、OOo.Calc の ソースコード(GetDiffDate360)  ( リンク切れ )
      を閲覧してみると PSA でコーディング (下記条件が抜けている) されていました。
        SIA 条件1: 開始日/終了日が共に2月末日ならば、終了日を 30日 に置換する。

    OOo.Calc 後継の LibreOffice の ソースコード ( ページ内を GetDiffDate360 で検索 )

〜 Google SpreadSheet 〜
  DAYS360 ( US )           …… 30/360(PSA)
  YEARFRAC ( US )        …… 30/360(PSA)
  YEARFRAC ( Act/Act ) …… ISDA方式に準拠 , 詳細は こちら を参照

〜 Excel (Office97〜2010 & Office365) 〜
  DAYS360 ( NASD )       …… 30/360(PSA)
  YEARFRAC ( NASD )    …… Excel97 : 30/360(SIA)
                                         Excel2000以降 : 30/360(SIA) , 一部バグあり
  YEARFRAC ( Act/Act ) …… 独自方式 ( 国際的な仕様とは全く異なる ) , 詳細は こちら を参照



 Home   Back Page   Next Page

ロゴ(ゴールド)   ロゴ(ゴールド)

角田 桂一 Mail:addinbox@h4.dion.ne.jp CopyRight(C) 2006 Allrights Reserved.