Add Months to a Date
Problem
Read a valid date (day month year) and an integer k (can be negative). Move the date by k months. If the new month has fewer days than the day of the month, use the last day of the new month instead (31 Jan + 1 month = 29 Feb in a leap year). Print the new date as: day month year. The result year stays between 1 and 9999.
Constraints
- The date is valid
- -1200 <= k <= 1200
Examples
Input
31 1 2024 1
Output
29 2 2024
Solutions
Months have different lengths, so adding months is not the same as adding 30 days. Counting months from year 0 turns the problem into one addition; floor division brings back the year and month. Java's LocalDate.plusMonths uses the same clamping rule.
/*
* Problem : Process a date.
* Input : One line of text.
* Output : The new date.
* Approach: day month year k.
* Time : O(1)
* Space : O(1)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static String solve(String s) {
// Step 1: Read day, month, year and the number of months to add.
String[] part = s.trim().split("\\s+");
int day = Integer.parseInt(part[0]);
int month = Integer.parseInt(part[1]);
int year = Integer.parseInt(part[2]);
int shift = Integer.parseInt(part[3]);
// Step 2: Count months from year 0. Then the shift is a plain addition. floorDiv works for negative values.
int total = year * 12 + (month - 1) + shift;
int newYear = Math.floorDiv(total, 12);
int newMonth = Math.floorMod(total, 12) + 1;
// Step 3: Find the length of the new month. February has 29 days in a leap year.
boolean leap = (newYear % 4 == 0 && newYear % 100 != 0) || newYear % 400 == 0;
int[] days = {31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// Step 4: Clamp the day to the length of the new month.
return Math.min(day, days[newMonth - 1]) + " " + newMonth + " " + newYear;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.hasNextLine() ? scanner.nextLine() : "";
System.out.println(solve(s));
}
}
Hints (1)
- Why is 31 Jan + 1 month not 31 Feb?