#きっかけ
.NET(C#)で書かれたコードを、JavaScriptで書き直す機会がありました。
指定日の一か月後、一か月前を計算する処理があったのですが、日付によっては.NET版とJavaScript版で結果が異なることがありました。
調査の結果、有効でない日付を指定した際の処理が異なることがわかりました。
#.NET
有効でない日付を指定した場合、最後の有効日が使用される。
例)
3月31日の一か月後
↓
4月31日(有効でない)
↓
4月30日(最後の有効日)
cs
DateTime date1 = new DateTime(2017, 3, 31);
Console.WriteLine(date1); // 3/31/2017 12:00:00 AM
Console.WriteLine(date1.AddMonths(1)); // 4/30/2017 12:00:00 AM
// DateTime date2 = new DateTime(2017, 4, 31); // これはエラー
// [System.ArgumentOutOfRangeException: Year, Month, and Day parameters describe an un-representable DateTime.]
#JavaScript
有効でない日付を指定した場合、月を繰り上げて有効な日付を再計算する。
例)
3月31日の一か月後
↓
4月31日(有効でない)
↓
5月1日(月を繰り上げて再計算した有効日)
js
// JavaScript の month は0(1月)~11(12月)なので、-1しています。
let date1 = new Date(2017, 3 - 1, 31);
console.log(date1); // Fri Mar 31 2017 00:00:00 GMT+0900 (東京 (標準時))
date1.setMonth(date1.getMonth() + 1);
console.log(date1); // Mon May 01 2017 00:00:00 GMT+0900 (東京 (標準時))
let date2 = new Date(2017, 4 - 1, 31); // これも設定可能
console.log(date2); // Mon May 01 2017 00:00:00 GMT+0900 (東京 (標準時))
#参考
.NET
https://msdn.microsoft.com/ja-jp/library/system.datetime.addmonths(v=vs.110).aspx
JavaScript
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCDate