-1

我正在尝试用其中的日期填充一个数组,

例如,这个月 August,它应该显示

Sunday Monday Tuesday Wednesday  ...  Saturday
null    1        2        3      ...     6
...     ...      ...     ...     ...     ...

它正在处理这个:

import java.time.LocalDate;
import java.util.Scanner;

public class buildCalendar {
    String[] calendar = new String[48];
    private final int firstDayOfMonth = 1;
    Scanner sc = new Scanner(System.in);
    int month, year;

    public buildCalendar() {
        System.out.println("Month: ");
        month = sc.nextInt();
        sc.nextLine();
        System.out.println("Year: ");
        year = sc.nextInt();

        newCalendar(month, year);
    }

    public void newCalendar(int month, int year) {
        LocalDate inputDate = LocalDate.of(year, month, firstDayOfMonth);
        int dayOfWeek = inputDate.withDayOfMonth(firstDayOfMonth).getDayOfWeek().getValue();


        // populate String array
        int i = 0;

        while (i <= calendar.length) {      
            if (i == dayOfWeek) {       
                for (int j = 0; j < inputDate.lengthOfMonth(); j++) {
                    calendar[i] = Integer.toString(i);
                    i++;                                    
                }
            }
            i++;
        }

        for (String string : calendar) {
            System.out.println(string);
        }
    }

}

但如果我决定将月份更改为 2016 年 1 月,那就错了。

Sunday Monday Tuesday Wednesday  Thursday Friday Saturday
null    null   null     null      null     5       6
...     ...      ...     ...     ...    ...     ...

5 应该是 1。你们会如何改变这个呢?

4

1 回答 1

0

因为无聊,我决定为此写一个完整的类,但略有不同。

String[48]我没有为天数创建一个数组,而是int[weeks][7]为该月的几周创建一个二维数组,其中weeks介于4和之间6,具体取决于该月的天数和该月第一天的工作日。的值0是“空白”日。

代码已得到增强,可以Locale感知,即确定一周是从星期日(例如美国)还是星期一(例如欧洲大部分地区)开始。

我还添加了一个不错的print()方法,它将打印给定的月份Locale,并自动调整输出大小。

核心输入是一个YearMonth标识月份和一个Locale. 与您的代码类似的基本逻辑是以下 7 行:

this.firstWeekdayOfWeek = WeekFields.of(this.locale).getFirstDayOfWeek();
DayOfWeek firstWeekdayOfMonth = this.yearMonth.atDay(1).getDayOfWeek();
int startWeekDay = (firstWeekdayOfMonth.getValue() - this.firstWeekdayOfWeek.getValue() + 7) % 7;
int endWeekDay = startWeekDay + this.yearMonth.lengthOfMonth();
this.weekdays = new int[(endWeekDay + 6) / 7][7];
for (int weekDay = startWeekDay, dayOfMonth = 1; weekDay < endWeekDay; weekDay++, dayOfMonth++)
    this.weekdays[weekDay / 7][weekDay % 7] = dayOfMonth;

如您所见,for循环使用 2 个迭代器变量,一个用于二维数组中的位置 ( weekDay),另一个用于分配的日期编号 ( dayOfMonth)。

这就是我处理您似乎遇到的问题的方式。

这是完整的课程:

public final class CalendarMonth implements Comparable<CalendarMonth> {
    private final YearMonth yearMonth;
    private final Locale    locale;
    private final DayOfWeek firstWeekdayOfWeek;
    private final int[][]   weekdays;

    public static CalendarMonth of(int year, int month) {
        return new CalendarMonth(YearMonth.of(year, month), Locale.getDefault());
    }
    public static CalendarMonth of(int year, int month, Locale locale) {
        Objects.requireNonNull(locale, "locale");
        return new CalendarMonth(YearMonth.of(year, month), locale);
    }
    public static CalendarMonth of(int year, Month month) {
        return new CalendarMonth(YearMonth.of(year, month), Locale.getDefault());
    }
    public static CalendarMonth of(int year, Month month, Locale locale) {
        Objects.requireNonNull(locale, "locale");
        return new CalendarMonth(YearMonth.of(year, month), locale);
    }
    public static CalendarMonth of(YearMonth yearMonth) {
        Objects.requireNonNull(yearMonth, "yearMonth");
        return new CalendarMonth(yearMonth, Locale.getDefault());
    }
    public static CalendarMonth of(YearMonth yearMonth, Locale locale) {
        Objects.requireNonNull(yearMonth, "yearMonth");
        Objects.requireNonNull(locale, "locale");
        return new CalendarMonth(yearMonth, locale);
    }

    private CalendarMonth(YearMonth yearMonth, Locale locale) {
        this.yearMonth = yearMonth;
        this.locale = locale;

        // Build weekdays array
        this.firstWeekdayOfWeek = WeekFields.of(this.locale).getFirstDayOfWeek();
        DayOfWeek firstWeekdayOfMonth = this.yearMonth.atDay(1).getDayOfWeek();
        int startWeekDay = (firstWeekdayOfMonth.getValue() - this.firstWeekdayOfWeek.getValue() + 7) % 7;
        int endWeekDay = startWeekDay + this.yearMonth.lengthOfMonth();
        this.weekdays = new int[(endWeekDay + 6) / 7][7];
        for (int weekDay = startWeekDay, dayOfMonth = 1; weekDay < endWeekDay; weekDay++, dayOfMonth++)
            this.weekdays[weekDay / 7][weekDay % 7] = dayOfMonth;
    }

    public void print() {
        // Get day names and determine width of longest name
        String[] dayName = new String[7];
        for (int i = 0; i < 7; i++)
            dayName[i] = this.firstWeekdayOfWeek.plus(i).getDisplayName(TextStyle.FULL, this.locale);
        int width = Arrays.stream(dayName).mapToInt(String::length).max().getAsInt();

        // Print month name
        String title = this.yearMonth.format(DateTimeFormatter.ofPattern("MMMM uuuu", this.locale));
        System.out.println(rightTrim(center(title, width * 7 + 6)));

        // Print day names
        StringBuilder line = new StringBuilder();
        for (int i = 0; i < 7; i++)
            line.append(center(dayName[i], width)).append(' ');
        System.out.println(rightTrim(line.toString()));

        // Print day numbers
        for (int[] week : this.weekdays) {
            line.setLength(0);
            for (int i = 0; i < 7; i++)
                line.append(center((week[i] == 0 ? "" : String.format("%2d", week[i])), width)).append(' ');
            System.out.println(rightTrim(line.toString()));
        }
    }
    private static String center(String text, int width) {
        if (text.length() >= width)
            return text;
        char[] buf = new char[width];
        Arrays.fill(buf, ' ');
        System.arraycopy(text.toCharArray(), 0, buf, (width - text.length() + 1) / 2, text.length());
        return new String(buf);
    }
    private static String rightTrim(String text) {
        return text.replaceFirst("\\s+$", "");
    }

    @Override
    public String toString() {
        return this.yearMonth.toString();
    }
    @Override
    public int compareTo(CalendarMonth that) {
        int cmp = this.yearMonth.compareTo(that.yearMonth);
        if (cmp == 0)
            cmp = this.locale.toLanguageTag().compareTo(that.locale.toLanguageTag());
        return cmp;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj instanceof CalendarMonth) {
            CalendarMonth other = (CalendarMonth) obj;
            return (this.yearMonth.equals(other.yearMonth) &&
                    this.locale.equals(other.locale));
        }
        return false;
    }
    @Override
    public int hashCode() {
        return Objects.hash(this.yearMonth, this.locale);
    }
}

测试

CalendarMonth.of(2016, Month.AUGUST).print();
CalendarMonth.of(2016, Month.JANUARY).print();
CalendarMonth.of(2016, Month.JANUARY, Locale.FRANCE).print();

输出

                             August 2016
  Sunday    Monday   Tuesday  Wednesday  Thursday   Friday   Saturday
               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
                             January 2016
  Sunday    Monday   Tuesday  Wednesday  Thursday   Friday   Saturday
                                                       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
                         janvier 2016
  lundi    mardi  mercredi   jeudi  vendredi  samedi  dimanche
                                        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

如您所见,它从星期一开始调整为一周,恰好将周数从 6 减少到 5。

于 2016-08-13T22:56:59.900 回答