3月31日に「来月の今日」と聞かれたらどちらと答えますか?
・4月30日
・5月1日
文字どおりに取ると『4月31日』であり即ち『5月1日』になります。
しかし一般人であれば『4月30日』をイメージすることが多いでしょう。
これはどちらが正しいというものでもなく、定義が曖昧なので解釈の隙があるというだけですね。
そんなわけでプログラミング言語においても、どちらを取るかは言語によってバラバラです。
以下はざっくりなんとなくの範囲で調べたものです。
言語機能にある場合はそれを、なければ一番有名っぽそうなライブラリを使っています。
4月30日
Csharp
DateTime.Parse("2020/03/31").AddMonths(1); // 2020-04-30
Java
var dt = LocalDate.parse("2020-03-31")
dt.plusMonths(1); // 2020-04-30
Kotlin
import java.time.LocalDate;
LocalDate.of(2020, 3, 31).plusMonths(1); // 2020-04-30
MySQL
SELECT '2020/03/31 00:00:00' + INTERVAL 1 MONTH // 2020-04-30
Oracle
SELECT ADD_MONTHS(DATE '2020-03-31', 1) FROM DUAL // 2020-04-30
SELECT DATE '2020-03-31' + INTERVAL '1' MONTH FROM DUAL // ORA-01839: date not valid for month specified
INTERVALを存在しない日付に使うとエラーになる。
PostgreSQL
SELECT timestamp '2020-03-31 00:00:00' + INTERVAL '1 MONTH' // 2020-04-30
Python
import datetime
from dateutil.relativedelta import relativedelta
print(datetime.datetime(2020, 3, 31, 0, 0, 0) + relativedelta(months=1)) // 2020-04-30
Ruby
from dateutil.relativedelta import relativedelta
from datetime import datetime
datetime(2020,3,31) + relativedelta(months=1) // 2020-04-30
Swift
import Foundation;
var calendar = Calendar.current;
let day = calendar.date(from: DateComponents(year: 2020, month: 3, day: 31))!;
let modifiedDate = Calendar.current.date(byAdding: .month, value: 1, to: day)!; // 2020-04-30
VisualBasic
Dim dt As DateTime = DateTime.Parse("2020/03/31").AddMonths(1) // 2020-04-30
民法
ただし、月又は年によって期間を定めた場合において、最後の月に応当する日がないときは、その月の末日に満了する。
5月1日
bash
date -d "2020/03/31 00:00:00 1 month" // 2020-05-01
Go
t := time.Date(2020, 3, 31, 0, 0, 0, 0, time.Local)
t.AddDate(0, 1, 0) // 2020-05-01
JavaScript
dt = new Date("2020/03/31 00:00:00");
dt.setMonth(dt.getMonth() + 1 ); // 2020-05-01
Perl
use Time::Piece;
Time::Piece->strptime("2020/03/31", "%Y/%m/%d")->add_months(1); // 2020-05-01
PHP
\DateTimeImmutable::createFromFormat('Y-m-d', '2020-03-31')->modify('next month'); // 2020-05-01
なでしこ
「2020/03/31」に「+0/1/0」を日付加算。
それを表示。 // 2020-05-01
その他
C
2020年4月31日。
int main(void){
time_t mk;
struct tm tm_mk;
struct tm *tm_lt;
tm_mk.tm_year = 2020 - 1900;
tm_mk.tm_mon = 3 - 1;
tm_mk.tm_mday = 31;
tm_mk.tm_hour = 0;
tm_mk.tm_min = 0;
tm_mk.tm_sec = 0;
mk = mktime(&tm_mk);
tm_lt = localtime(&mk);
tm_lt->tm_mon++;
printf("%04d/%02d/%02d", tm_lt->tm_year + 1900, tm_lt->tm_mon + 1, tm_lt->tm_mday); // 2020/04/31
}
Rust
一ヶ月後を探し出せなかった。
まとめ
4月30日派が多いけど、決定的というほどでもないですね。