3か月後は何日?


2013年 08月 23日

1月31日の3ヶ月後は何月何日だろう?
C#で書くとこうなります
 DateTime d = DateTime.Parse("2012/1/31");
 d = d.AddMonths(3);
まあ皆さんの想像の通り4月30日になるわけですが少し前にこれが困った事態を引き起こしました。
図書館システムで返却日は貸出日の3ヶ月後というルールがあって、その通り計算していたのですが、それが上記のケースだったわけです。現場の感覚としては貸出期間が3か月未満になっておかしいということでした。
正直AddMonthsがありえない日を計算(上記では4月31日)を計算したときにどうなるのか全く知りませんでした。
ちょっと調べると(まあ調べるまでもないですが)表現可能なように日にち部分が削られるのが仕様なようです。まあデフォルトの動作はそんなものかな?と思って、じゃあこのようなケースで5月1日を返すようなオプションがあるのだろう、と探してみましたが… 見当たらない。あってもよさそうなものだけどなと思いながら、しょうがないので自分でルーチンを組みました。
組んでみて納得。AddMonthsの引数がマイナスの場合(さかのぼる)場合には「表現可能なように日にち部分が削られる」という今の仕様でないとうまくいかないですね。勝手に次の月にしたいケースは思いつきません。自作のルーチンではマイナスの場合は普通のAddMonthを呼ぶようにしました。
たぶんほかの言語でも同じだと思います。調べるの面倒なので調べませんが。
まあしょうもないネタですがDateTimeなんてありきたりのクラスにもまだまだ未知の部分があると知ってフレームワークの偉大さを再確認しました。