Skip to content

Instantly share code, notes, and snippets.

@aa65535
Last active September 21, 2015 14:30
Show Gist options
  • Save aa65535/c9a5ba1451cce97d2af7 to your computer and use it in GitHub Desktop.
Save aa65535/c9a5ba1451cce97d2af7 to your computer and use it in GitHub Desktop.
Print formatted calendar
package calendar;
public class TestCalendar {
public static void main(String[] args) {
ViewCalendar vc = new ViewCalendar(2015);
vc.print();
// vc.print(9);
}
}
package calendar;
import java.util.*;
public class ViewCalendar {
private int year;
private String headOfWeek = "日\t一\t二\t三\t四\t五\t六";
// 默认为 1970 年
public ViewCalendar() {
setYear(1970);
}
public ViewCalendar(int year) {
this();
setYear(year);
}
public int getYear() {
return year;
}
public void setYear(int year) {
if (year < 1)
System.err.println("错误的年份!");
else
this.year = year;
}
// 打印全年日历
public void print() {
final byte NUM_OF_MONTH = 3; // 并列显示的月数
byte[] day = new byte[12];
boolean[][] arrayOfYear = getCalendar();
String result = "";
// 12 个月被划分为 (12 / NUM_OF_MONTH) 部份
for (int i = 0; i < arrayOfYear.length / NUM_OF_MONTH; i++) {
// 打印星期表头
for (int j = 1; j < NUM_OF_MONTH; j++)
result += headOfWeek + "\t\t";
result += headOfWeek + "\n";
// 每个月数组被分为 6 行, m 为当前行数
for (int m = 0; m < 6; m++) {
// 遍历分成 (12 / NUM_OF_MONTH) 份的月份, k 为当前月份
for (int k = i * NUM_OF_MONTH; k < (i + 1) * NUM_OF_MONTH; k++) {
// 每周 7 天, 所以需要遍历 7 次
for (int n = 0; n < 7; n++)
// m * 7 + n 为月数组当前遍历的位置
if (arrayOfYear[k][m * 7 + n])
result += (++day[k] < 10 ? " " + day[k] : day[k]) + "\t";
else
result += "\t";
result += "\t";
}
result += "\n";
}
}
System.out.println(result.replaceAll("\t*\n", "\n"));
}
// 打印指定月份的日历
public void print(int month) {
if (month < 1 || month > 12) {
System.err.println("错误的月份,有效值范围[1-12]");
return;
}
byte day = 0;
boolean flag = false;
boolean[] arrayOfMonth = getCalendar(month - 1);
System.out.println(headOfWeek);
for (int i = 1; i < arrayOfMonth.length; i++) {
if (arrayOfMonth[i - 1]) {
System.out.print(++day < 10 ? " " + day : day);
flag = true; // 为 true 表示正在遍历数组为 true 的部分
}
// 7 列的时候直接换行并进行下一次循环
if (i % 7 == 0) {
System.out.println();
continue;
}
// 开始遍历为 true 部分后, 当下一位置为 false 则打印一个换行后终止循环
if (flag && !arrayOfMonth[i]) {
System.out.println();
break;
}
System.out.print("\t");
}
}
// 返回指定月份的天数, 2 月需要另外判断
private int getDays(int month) {
int[] days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
return days[month];
}
// 返回全年数组, 二维数组, 元素为 getCalendar(int month) 方法返回的数组
private boolean[][] getCalendar() {
boolean[][] arrayOfYear = new boolean[12][];
for (int month = 0; month < 12; month++)
arrayOfYear[month] = getCalendar(month);
return arrayOfYear;
}
// 返回指定月份的数组, 里面存放布尔值, 根据其值判断是否打印日期
// 此处的 month 取值范围为 [0-11]
private boolean[] getCalendar(int month) {
boolean[] arrayOfMonth = new boolean[42];
GregorianCalendar gc = new GregorianCalendar(year, month, 1);
int initSpace = gc.get(Calendar.DAY_OF_WEEK) - 1;
int daysInMonth = getDays(month);
// 闰年判断
if (month == 1 && gc.isLeapYear(gc.get(Calendar.YEAR)))
daysInMonth++;
// 对有日期的部分进行填充
while (daysInMonth-- > 0)
arrayOfMonth[initSpace++] = true;
return arrayOfMonth;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment