Here's a summary of how to handle invalid dates such as February 31st in each language. PHP
<?php
$target_date = "2017-01-31";
for ($i=0; $i < 6; $i++) {
echo date('Y-m-d', strtotime($target_date . '+' . $i . ' month')) . "\n";
}
?>
2017-01-31
2017-03-03
2017-03-31
2017-05-01
2017-05-31
2017-07-01
In PHP strtotime (), one month after 2017-01-31, it becomes "2017-02-31". "2017-02-31" is interpreted as "2017-03-03".
JavaScript
var date = new Date(2017 ,1 - 1, 31);
for (var i=0; i < 6; i++) {
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
console.log(year + '-' + month + '-' + day);
//Increase the month by 1
date.setMonth(date.getMonth() + 1);
}
2017-1-31
2017-3-3
2017-4-3
2017-5-3
2017-6-3
2017-7-3
In the case of JavaScript Date class, as with PHP, one month after 2017-01-31, it will be "2017-02-31". "2017-02-31" is interpreted as "2017-03-03". Since setMonth () is a destructive method, it will remain for 3 days after 2017-3-3.
Java
import java.util.Calendar;
import java.text.SimpleDateFormat;
public class Main {
public static void main(String[] args) throws Exception {
Calendar calendar = Calendar.getInstance();
calendar.set(2017, 1 - 1, 31);
//Set the display format
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
//Increase the month by 1
for (int i = 0 ; i < 6 ; i++){
System.out.println(sdf1.format(calendar.getTime()));
calendar.add(Calendar.MONTH, 1);
}
}
}
2017-01-31
2017-02-28
2017-03-28
2017-04-28
2017-05-28
2017-06-28
In the case of Java's Calendar class, the day is also changed to 28 if the month after the increase is only up to 28 days. Even if there is a month until the 31st after that, the day remains the 28th.
Ruby
require "date"
date = Date.new(2017, 1 ,31)
for i in 0..5
puts((date >> i).strftime("%Y-%m-%d"))
end
2017-01-31
2017-02-28
2017-03-31
2017-04-30
2017-05-31
2017-06-30
Ruby's Date class outputs the last day beautifully.