n日後を返す関数を返す関数、どう書く?(Mathematica)

n日後を返す関数を返す関数(どう書く?org)

整数nを渡すと「日時のデータを受け取って、n日後の日時を返す関数」を返す関数を作ってください。

これはそんなに簡単な問題じゃない。すでにアップされているものの中に正解はなさそう。満足できるものを作るにはかなりの手間がかかるはず。ここでも、そこまではしない

面倒だから、日本限定、nは0以上、西暦限定、暦はユリウス暦とグレゴリオ暦のみ、妥当な日付が入力されることにしよう

Mathematicaでは、1752年9月14日にユリウス暦からグレゴリオ暦に切り替わったことになっている

<<Miscellaneous`Calendar` (Version 6では「<<Calendar`」)

DaysPlus[{1752, 9, 2}, 1] (1752年9月2日の翌日は)

{1752, 9, 14}

でも、日本の場合、切り替わったのは明治6(西暦1873)年1月1日だから、このまま使うわけにはいかない(厳密に言えば、旧暦とグレゴリオ暦の差を詰めたのが明治6年、グレゴリオ暦の置閏法を採用したのが明治31年)

  • 入力が1873年1月1日より前ならユリウス暦で計算
    • 結果が1892年12月2日より後ならグレゴリオ暦に変換
    • そうでなければそのまま
  • そうでなければグレゴリオ暦で計算
nDaysLater[n_] := Function[{d},
    Module[{tmp},
      If[{10000, 100, 1}. d < 18730101,
        tmp = DaysPlus[d, n, Calendar -> Julian];
        If[18721202 < {10000, 100, 1}. tmp,
          DaysPlus[{1873, 1, 1}, DaysBetween[{1872, 12, 3}, tmp, Calendar -> Julian]],
          tmp],
        DaysPlus[d, n]]]]
nDaysLater[1]@{1752, 9, 2}

{1752, 9, 3} (異常なし)
nDaysLater[1]@{1872, 12, 2}

{1873, 1, 1} (暦が切り替わった)
nDaysLater[5]@{2007, 7, 20}

{2007, 7, 25} (異常なし)

Javaの暦に関しては、拙著『Webアプリケーション構築入門 実践!Webページ制作からマッシュアップまで 』(森北出版, 2011)で解説しています。