Core Java 8 学习笔记(四) 打印一个简单的日历

一、概述

Java中和时间日期有关的有三个类,Date,Calendar和GregorianCalendar。弄清楚这三个类的关系和使用方法,对时间的处理就绰绰有余了!拿来熟悉Java中的类也是蛮好的选择,这本书第四章开头,介绍对象与类就是这样做的。

Date顾名思义,只能处理时分秒,不能处理年月日。GregorianCalendar中文翻译是格里高利历,即国际上通用的阳历,或者公历,具体的历史可以去参考百度百科。GregorianCalendar是Calendar的一个子类,但是多了很多使用的方法和属性,也很容易和Date类相互转换。你如果想实现一个火星日历,可以通过拓展Calenlar来实现。


二、常见的属性和方法

Date类只提供少量的方法,如 if(today.before(someDay)) ... 这里的before函数(当然也有after函数)会返回一个布尔值。

Calendar类里有一些比较常用的静态变量,如

Calendar.JANUARY; //1月份
Calendar.DECEMBER; // 12月份
Calendar.DAY_OF_MONTH; // 本月的第几天
Calendar.DAY_OF_WEEK; // 这星期的第几天
Calendar.DAY_OF_WEEK_IN_MONTH; // 这个月的第几个星期
Calendar.DAY_OF_YEAR; // 这一年的第几天
GregorianCalendar的构造函数很好用,VS可以自动提示格式,不用硬记。一个实例可以调用get函数和拓展来改变得到年月日,为int值;可以用set和add改变这些值。


三、打印一个日历。

打印如下格式的日历作为练习:


注意不同的国家每周的开头可能不一样,如美国是以周日作为一周的第一天,而欧洲则是认为每星期的开头一天是周一。GregorianCalendar提供一个getFirstDayOfWeek来得到一周的头一天。Locale.setDefault(Locale.CHINA);可以用来设置国家,同时星期的显示方式也不一样。

最后的日本的首行没有对齐,韩国的有乱码,可能都是编码问题吧,不知道该咋个解决呢?

具体的完整代码和解释如下:

package v1_chapter4;

import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;

public class MyCalendar {
	
	public static void printCalendar()
	{
		System.out.printf("设置日历的国家或区域是  %s.\n", Locale.getDefault().getDisplayCountry());
		
		GregorianCalendar currentDate = new GregorianCalendar(); // 构造一个日历,为当前日期
		
		int today = currentDate.get(Calendar.DAY_OF_MONTH); // get函数,根据参数可以得到“日”
		
		// set currentDate to start date of this month
		currentDate.set(Calendar.DAY_OF_MONTH, 1); 	// 设置当前“日”为1号
		
		// the weekday of the first day of this month;
		int firstWeekday = currentDate.get(Calendar.DAY_OF_WEEK); // 1号是周几?
		
		// get default first day of week(Sunday in the U.S, but Monday in Europe)
		int firstDayOfWeek = currentDate.getFirstDayOfWeek(); // 此国家和地区的周几是每星期的头一天(周日?周一?)
		
		// determine the required indentation for the first line
		int indent = 0; // 第二行的缩进数目
		while(firstWeekday != firstDayOfWeek)
		{
			// 这段代码改了好几次,最后还是用while来模拟实现。indent = Math.abs(firstDayOfWeek - firstWeekday)是不行的。
			indent += 1;
			currentDate.add(Calendar.DAY_OF_MONTH, -1);
			firstWeekday = currentDate.get(Calendar.DAY_OF_WEEK);
		}
		
		// 返回的这个数组很好用,下表1-7分别表示周日到周六
		String[] weekdayNamesStrings = new DateFormatSymbols().getShortWeekdays();
		for(int i = 0; i < 7; ++ i)
		{
			// 哈哈,这个格式化好麻烦,要包证两种日历都能正确输出,尝试了很多次才写对,慢慢琢磨吧,我也说不清。
			System.out.printf("%4s ", weekdayNamesStrings[(i + firstDayOfWeek - 1) % 7 + 1]);
		}
		System.out.println();
		
		for(int i = 0; i < indent; ++ i)
		{
			System.out.print("     "); // 5 blanks
		}
		
		// 这个月最多有几天?days天!这个函数的用途不止于此。
		int days = currentDate.getActualMaximum(Calendar.DAY_OF_MONTH);
		
		for(int i = 0; i < days; ++ i)
		{
			System.out.printf("%4d", i + 1);
			if(today == i+1)
				System.out.print("*"); // *号表示今天,不是今天则输出空格
			else {
				System.out.print(" ");
			}
			if((indent + i + 1) % 7 == 0)
				System.out.println();
		}
		System.out.println("\n\n");
	}
	
	public static void main(String args[])
	{
		Locale.setDefault(Locale.CHINA); // 中国
		printCalendar();
		Locale.setDefault(Locale.US); // 美国
		printCalendar();
		Locale.setDefault(Locale.UK); // 英国
		printCalendar();
		Locale.setDefault(Locale.FRANCE); // 法国
		printCalendar();
		Locale.setDefault(Locale.JAPAN); // 日本
		printCalendar();
		Locale.setDefault(Locale.KOREA); // 韩国
		printCalendar();
		
	}
}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值