英文:
How to Properly print Month Calendar on Terminal
问题
import java.util.*;
public class CalendarMonthDisplay {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入一个介于1到12之间的月份(例如:5):");
int m = input.nextInt();
System.out.print("请输入一个完整的年份(例如:2018):");
int y = input.nextInt();
if (m < 1 || m > 12)
System.out.print("输入错误!请重新尝试。");
else
printMonthCalendar(m, y);
}
static void printMonthCalendar(int m, int y) {
int startDay = getStartDay(m, y);
int numDaysInMonths = getNumDaysInMonth(m, y);
printMonthHeader(m, y);
printMonthBody(startDay, numDaysInMonths);
}
static void printMonthBody(int startDay, int numDaysInMonths) {
int i;
for (i = 0; i <= startDay; i++)
System.out.print(" ");
for (i = 1; i <= numDaysInMonths; i++) {
if (i < 10)
System.out.print(" " + i);
else
System.out.print(" " + i);
if ((startDay + i) % 7 == 0)
System.out.println();
}
System.out.println();
}
static void printMonthHeader(int m, int y) {
System.out.println("\t" + getMonthName(m) + " " + y);
System.out.println("------------------------------");
System.out.println(" Sun Mon Tue Wed Thu Fri Sat");
}
static String getMonthName(int m) {
String monthName = null;
switch (m) {
case 1:
monthName = "一月";
break;
case 2:
monthName = "二月";
break;
case 3:
monthName = "三月";
break;
case 4:
monthName = "四月";
break;
case 5:
monthName = "五月";
break;
case 6:
monthName = "六月";
break;
case 7:
monthName = "七月";
break;
case 8:
monthName = "八月";
break;
case 9:
monthName = "九月";
break;
case 10:
monthName = "十月";
break;
case 11:
monthName = "十一月";
break;
case 12:
monthName = "十二月";
}
return monthName;
}
static int getNumDaysInMonth(int m, int y) {
int numDaysInMonths = 0;
switch (m) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
numDaysInMonths = 31;
break;
case 4:
case 6:
case 9:
case 11:
numDaysInMonths = 30;
break;
case 2:
if (isLeapYear(y))
numDaysInMonths = 29;
else
numDaysInMonths = 28;
break;
}
return numDaysInMonths;
}
static boolean isLeapYear(int y) {
return (y % 400 == 0) || (y % 4 == 0 && y % 100 != 0);
}
static int getStartDay(int m, int y) {
if (m < 3)
m = m + 12;
y = y - 1;
int d = 1;
int k = y % 100;
int j = y / 100;
int h = 0;
h = (d + (13 * (m + 1) / 5) + k + (k / 4) + (j / 4) + (5 * j)) % 7;
int dayNum = ((h + 5) % 7) + 1;
return dayNum;
}
}
英文:
Hello and thanks in advance for the assistance. I have a program that is supposed to print the current month calendar based on the user inputs of month and year. The program mostly work but i am having issues with formatting and the first day of the month is not starting under the proper date.
Example output:
October 2020
------------------------------
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
October 2020 will begin on a Thursday, but 1
is printed under Mon
. October 4th is a Sunday, so that is where the new line should begin.
Please see attached my code. Thanks again
import java.util.*;
public class CalendarMonthDisplay {
public static void main(String[] args) {
Scanner input = new Scanner(System.in); //Scan for user input
System.out.print("Please enter a month between 1 and 12 (e.g. 5): "); //Prompt user to enter month
int m = input.nextInt();
System.out.print("Please enter a full year (e.g. 2018): "); //Prompt user to enter year
int y = input.nextInt();
//Print calendar for the month of the year
if ( m < 1 || m > 12)
System.out.print("Wrong input! Please try again.");
else
printMonthCalendar(m, y);
}
static void printMonthCalendar (int m, int y) { //Display calendar in format above
int startDay = getStartDay(m, y);
int numDaysInMonths = getNumDaysInMonth(m, y);
printMonthHeader(m, y);
printMonthBody(startDay, numDaysInMonths);
}
static void printMonthBody (int startDay, int numDaysInMonths) { //Display the days in the calendar
int i;
for (i = 0; i <= startDay; i++)
System.out.print(" ");
for (i = 1; i <= numDaysInMonths; i++) {
if ( i < 10 )
System.out.print(" " + i );
else
System.out.print(" " + i + " ");
if ((startDay + i) % 7 == 0)
System.out.println();
}
System.out.println();
}
static void printMonthHeader (int m, int y) { //Display the header information
System.out.println("\t" + getMonthName(m) + " " + y);
System.out.println("------------------------------");
System.out.println(" Sun Mon Tue Wed Thu Fri Sat");
}
static String getMonthName (int m) {
String monthName = null;
switch (m) {
case 1: monthName = "January";
break;
case 2: monthName = "February";
break;
case 3: monthName = "March";
break;
case 4: monthName = "April";
break;
case 5: monthName = "May";
break;
case 6: monthName = "June";
break;
case 7: monthName = "July";
break;
case 8: monthName = "August";
break;
case 9: monthName = "September";
break;
case 10: monthName = "October";
break;
case 11: monthName = "November";
break;
case 12: monthName = "December";
}
return monthName;
}
static int getNumDaysInMonth (int m, int y) {
int numDaysInMonths= 0;
switch (m) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
numDaysInMonths= 31;
break;
case 4: case 6: case 9: case 11:
numDaysInMonths = 30;
break;
case 2:
if (isLeapYear(y))
numDaysInMonths = 29;
else
numDaysInMonths = 28;
break;
}
return numDaysInMonths;
}
static boolean isLeapYear (int y) {
return (y % 400 == 0) || (y % 4 == 0 && y % 100 != 0);
// return true;
// return false;
}
static int getStartDay (int m, int y) {
// Adjust month number & year to fit Zeller's numbering system
if (m < 3)
m = m + 12;
y = y - 1;
int d = 1; //Set day parameter to 1
int k = y % 100; // Calculate year within century
int j = y / 100; // Calculate century term
int h = 0; // Day number of first day in month 'm'
h = ( d + ( 13 * ( m + 1 ) / 5 ) + k + ( k / 4 ) + ( j / 4 ) + ( 5 * j ) ) % 7;
// Convert Zeller's value to ISO value (1 = Mon, ... , 7 = Sun )
int dayNum = ( ( h + 5 ) % 7 ) + 1;
return dayNum;
}
}
答案1
得分: 1
我建议您使用现代日期时间 API来完成此操作。从**Trail: Date Time**了解有关现代日期时间 API 的更多信息。
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in); // 扫描用户输入
System.out.print("请输入一个介于 1 到 12 之间的月份 (例如 5):"); // 提示用户输入月份
int m = input.nextInt();
System.out.print("请输入一个完整的年份 (例如 2018):"); // 提示用户输入年份
int y = input.nextInt();
printMonth(y, m);
}
static void printMonth(int year, int month) {
YearMonth ym = YearMonth.of(year, month);
System.out.println("Sun Mon Tue Wed Thu Fri Sat");
int counter = 1;
// 获取该月第一天的星期几,并打印与星期日相隔的空格数
int dayValue = LocalDate.of(year, month, 1).getDayOfWeek().getValue();
for (int i = 0; i < dayValue; i++, counter++) {
System.out.printf("%-4s", "");
}
for (int i = 1; i <= ym.lengthOfMonth(); i++, counter++) {
System.out.printf("%-4d", i);
// 如果计数器的值是 7 的倍数,换行
if (counter % 7 == 0) {
System.out.println();
}
}
}
}
一个示例运行:
请输入一个介于 1 到 12 之间的月份 (例如 5):9
请输入一个完整的年份 (例如 2018):2020
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
注意: 了解有关格式化打印的内容,请访问Formatter。
英文:
I recommend you do it using the modern date-time API. Learn more about the modern date-time API from Trail: Date Time.
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in); // Scan for user input
System.out.print("Please enter a month between 1 and 12 (e.g. 5): "); // Prompt user to enter month
int m = input.nextInt();
System.out.print("Please enter a full year (e.g. 2018): "); // Prompt user to enter year
int y = input.nextInt();
printMonth(y, m);
}
static void printMonth(int year, int month) {
YearMonth ym = YearMonth.of(year, month);
System.out.println("Sun Mon Tue Wed Thu Fri Sat");
int counter = 1;
// Get day of week of 1st date of the month and print space for as many days as
// distant from SUN
int dayValue = LocalDate.of(year, month, 1).getDayOfWeek().getValue();
for (int i = 0; i < dayValue; i++, counter++) {
System.out.printf("%-4s", "");
}
for (int i = 1; i <= ym.getMonth().length(ym.isLeapYear()); i++, counter++) {
System.out.printf("%-4d", i);
// Break the line if the value of the counter is multiple of 7
if (counter % 7 == 0) {
System.out.println();
}
}
}
}
A sample run:
Please enter a month between 1 and 12 (e.g. 5): 9
Please enter a full year (e.g. 2018): 2020
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Note: Learn about formatted printing at Formatter.
答案2
得分: 0
我认为你的getStartDay
方法返回的星期几数字与你期望的不符。似乎对于从周三到周二,它返回1到7不等的数字。示例:
月份 开始的星期几 getStartDay()
------------------------------------------------
2020年7月 周三 1
2020年8月 周六 4
2020年9月 周二 7
2020年10月 周四 2
你的代码中可能还有一两个问题,但我认为你应该先解决这个根本性的问题。
这是一个不错的练习,你肯定在学习中。对于生产代码,永远不会实现Zeller算法或任何其他用于找到月份长度和星期几的算法。标准库可以更可靠地完成这个任务,正如Arvind Kumar Avinash在答案中所示。
英文:
I don’t think your getStartDay
method returns the day of week number that you expect. It seems to be returning 1 for Wednesday through 7 for Tuesday. Examples:
Month Start day of week getStartDay()
------------------------------------------------
July 2020 Wednesday 1
August 2020 Saturday 4
September 2020 Tuesday 7
October 2020 Thursday 2
There is probably one or two more problems in your code, but I think you should fix this fundamental one first.
It’s a fine exercise, you’re surely learning. For production code one would never implement Zeller’s algorithm or any other algorithm for finding lengths of months and days of week. This is done much more reliably by the standard library as shown in the answer by Arvind Kumar Avinash.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论