fork download
  1. import java.util.ArrayList;
  2. import java.util.Collections;
  3. import java.util.List;
  4. import java.util.Scanner;
  5.  
  6. class Koyomi {
  7. public static void main(String[] args) {
  8. IntegerScanner intScanner = new IntegerScanner(new Scanner(System.in));
  9. int year = intScanner.read("Year?", 2000, 2040);
  10. int month = intScanner.read("Month?", 1, 12);
  11. new Calendar().print(year, month);
  12. }
  13. }
  14.  
  15. class Calendar {
  16. public void print(int year, int month){
  17. int monthNext, yearNext;
  18. if(month == 12){
  19. monthNext = 1;
  20. yearNext = year + 1;
  21. }else{
  22. monthNext = month + 1;
  23. yearNext = year;
  24. }
  25.  
  26. int z1 = calcZeller(year, month);
  27. int z2 = calcZeller(yearNext, monthNext);
  28. int lastDate = getLastDateOfMonth(z1, z2);
  29. int pad = convertToDayOfTheWeekIndex(z1);
  30.  
  31. System.out.printf("\n %d年 %d月\n日 月 火 水 木 金 土\n", year, month);
  32. List<String> list = new ArrayList<String>(Collections.nCopies(pad, " "));
  33. int i = pad;
  34. for(int date = 1; date <= lastDate; date++){
  35. list.add(String.format("%2d", date));
  36. if(++i == 7){
  37. System.out.println(String.join(" ", list));
  38. list.clear();
  39. i = 0;
  40. }
  41. }
  42. if(list.size() > 0){
  43. System.out.println(String.join(" ", list));
  44. }
  45. }
  46. /** ツェラーの式による曜日番号計算 (0=土曜日) */
  47. int calcZeller(int year, int month) {
  48. if (month <= 2) {
  49. month += 12;
  50. year -= 1;
  51. }
  52. int j = year / 100;
  53. int k = year % 100;
  54. int a = (month + 1) * 26 / 10;
  55. int z = (1 + a + k + k / 4 + j / 4 - 2 * j) % 7;
  56. if(z < 0) {
  57. z += 7;
  58. }
  59. return z;
  60. }
  61. /** ツェラーの計算結果を曜日インデックス(0=日曜)に変換 */
  62. int convertToDayOfTheWeekIndex(int zeller) {
  63. return zeller == 0 ? 6 : zeller - 1;
  64. }
  65. /** 対象月初日と翌月初日の曜日のギャップから月の最終日(日数)を計算 */
  66. int getLastDateOfMonth(int zeller1, int zeller2){
  67. int gap = zeller2 - zeller1;
  68. if(gap < 0){
  69. gap += 7;
  70. }
  71. return 28 + gap;
  72. }
  73. }
  74.  
  75. class IntegerScanner {
  76. private Scanner scanner;
  77. public IntegerScanner(Scanner scanner) {
  78. this.scanner = scanner;
  79. }
  80. public int read(String message, int min, int max) {
  81. while (true) {
  82. System.out.printf("%s [%d-%d] > ", message, min, max);
  83. String line = this.scanner.nextLine();
  84. try {
  85. int n = Integer.parseInt(line);
  86. if (min <= n && n <= max) {
  87. return n;
  88. } else {
  89. System.out.println("範囲外です");
  90. }
  91. } catch (NumberFormatException e) {
  92. System.out.println("正しい入力ではありません。");
  93. }
  94. }
  95. }
  96. }
  97.  
Success #stdin #stdout 0.12s 29520KB
stdin
100000
a
2018
6
stdout
Year? [2000-2040] > 範囲外です
Year? [2000-2040] > 正しい入力ではありません。
Year? [2000-2040] > Month? [1-12] > 
     2018年 6月
日 月 火 水 木 金 土
                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