8.Java日期时间

日期工具Date

需要先创建一个Date实例,默认保存的是系统时间,但是Date问世比较早,很多功能用起来不方便:
获取年份:+1900才是真正的公元年份,因为他是从1900开始计数的
获取月份:+1才是真正的月份,因为他是从0开始计数的
获取星期:需要修正getDay的结果,将星期天改为7,否则输出为0
获取时分秒没有需要修正的地方

		Date date = new Date(); // 创建一个新的日期实例,默认保存的是系统时间
		int year = date.getYear() + 1900; // 获取日期实例中的年份
		System.out.println("year=" + year);
		int month = date.getMonth() + 1; // 获取日期实例中的月份
		System.out.println("month=" + month);
		int day = date.getDate(); // 获取日期实例中的日子
		System.out.println("day=" + day);
		int dayWeek = date.getDay(); // 获取日期实例中的星期几
		dayWeek = (dayWeek == 0) ? 7 : dayWeek; // 将星期日对应的数值改为7
		System.out.println("dayWeek=" + dayWeek);
		int hour = date.getHours(); // 获取日期实例中的时钟
		System.out.println("hour=" + hour);
		int minute = date.getMinutes(); // 获取日期实例中的分钟
		System.out.println("minute=" + minute);
		int second = date.getSeconds(); // 获取日期实例中的秒钟
		System.out.println("second=" + second);
		long time = date.getTime(); // 获取日期实例中的时间总数(单位毫秒)
		System.out.println("time=" + time);

year=2021
month=7
day=13
dayWeek=2
hour=10
minute=32
second=19
time=1626143539107

日期的格式化也比较麻烦,总之代码冗余比较严重,一般不推荐这种方法!!!

日历工具Calendar

因为Date的先天不足,Java又提供了一个Calendar日历工具
与Date有几点区别说明一下:

1.创建日历实例需要用getInstance方法,而不用new关键字
2. Calendar的月份也是从0开始的,所以月份需要+1
3. Date的星期是从0开始的,但是日历的星期是从1开始计数,虽然比起Date算是进步了,但是仍然是星期天开头,星期六结尾就很难受。。。所以需要在原来的基础上把星期天变成7,其余星期-1

		Calendar calendar = Calendar.getInstance(); // 创建一个日历实例
		int year = calendar.get(Calendar.YEAR); // 获取日历实例中的年份
		System.out.println("year=" + year);
		int month = calendar.get(Calendar.MONTH) + 1; // 获取日历实例中的月份
		System.out.println("month=" + month);
		int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); // 获取日历实例中的日子
		System.out.println("dayOfMonth=" + dayOfMonth);
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); // 获取日历实例中的星期几
		dayOfWeek = dayOfWeek == 1 ? 7 : dayOfWeek - 1;
		System.out.println("dayOfWeek=" + dayOfWeek);
		int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR); // 获取日历实例中从年初开始数的日子
		System.out.println("dayOfYear=" + dayOfYear);
		int hour = calendar.get(Calendar.HOUR); // 获取日历实例中的时钟(12小时制)
		System.out.println("hour=" + hour);
		int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); // 获取日历实例中的时钟(24小时制)
		System.out.println("hourOfDay=" + hourOfDay);
		int minute = calendar.get(Calendar.MINUTE); // 获取日历实例中的分钟
		System.out.println("minute=" + minute);
		int second = calendar.get(Calendar.SECOND); // 获取日历实例中的秒钟
		System.out.println("second=" + second);
		int milliSecond = calendar.get(Calendar.MILLISECOND); // 获取日历实例中的毫秒
		System.out.println("milliSecond=" + milliSecond);

4.Calendar提供了set方法,可以修改某个时间单位

Calendar calendar = Calendar.getInstance(); // 创建一个日历实例
		// 调用带三个参数的set方法同时设置日历实例的年、月、日
		calendar.set(2019, 11, 27);
		// 调用带六个参数的set方法同时设置日历实例的年、月、日、时、分、秒
		calendar.set(2019, 11, 27, 12, 30, 40);
		System.out.println("begin set dayOfMonth="
				+ calendar.get(Calendar.DAY_OF_MONTH));
		// 带两个参数的set方法允许把某个时间单位改为指定数值
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		System.out.println("end set dayOfMonth=" + calendar.get(Calendar.DAY_OF_MONTH));
		System.out.println("begin set hourOfDay=" + calendar.get(Calendar.HOUR_OF_DAY));
		// 联合使用get和set方法,可对某个时间单位增减
		int dayResult = calendar.get(Calendar.HOUR_OF_DAY) + 1; // 给当前日期加上一天
		calendar.set(Calendar.HOUR_OF_DAY, dayResult); // 设置日历实例中的日期
		System.out.println("end set hourOfDay="
				+ calendar.get(Calendar.HOUR_OF_DAY));
		System.out.println("begin set minute=" + calendar.get(Calendar.MINUTE));
		// 调用add方法,直接在当前时间的基础上增加若干数值
		calendar.add(Calendar.MINUTE, 10); // 给当前时间加上10分钟
		System.out.println("end add minute=" + calendar.get(Calendar.MINUTE));

5.Calendar类型与date类型互相转换

// 把Calendar类型的数据转换为Date类型
	private static void convertCalendarToDate() {
		Calendar calendar = Calendar.getInstance(); // 创建一个日历实例
		Date date = calendar.getTime(); // 调用日历实例的getTime方法,获得日期信息
		System.out.println("日历转日期 date=" + date.toString() + ", calendar=" + calendar.toString());
	}

	// 把Date类型的数据转换为Calendar类型
	private static void convertDateToCalendar() {
		Calendar calendar = Calendar.getInstance(); // 创建一个日历实例
		Date date = new Date(); // 创建一个日期实例
		calendar.setTime(date); // 调用日历实例的setTime方法,设置日期信息
		System.out.println("日期转日历 date=" + date.toString() + ", calendar=" + calendar.toString());
	}

6.如何计算日历时间的天数?

private static void countDays() {
		Calendar calendarA = Calendar.getInstance(); // 创建一个日历实例
		calendarA.set(2019, 3, 15); // 设置第一个日历实例的年月日
		Calendar calendarB = Calendar.getInstance(); // 创建一个日历实例
		calendarB.set(2019, 9, 15); // 设置第二个日历实例的年月日
		long timeOfA = calendarA.getTimeInMillis(); // 获得第一个日历实例包含的时间总数(单位毫秒)
		long timeOfB = calendarB.getTimeInMillis(); // 获得第二个日历实例包含的时间总数(单位毫秒)
		// 先计算二者的差额,再把毫秒计量的差额转换为天数
		long dayCount = (timeOfB - timeOfA) / (1000 * 60 * 60 * 24);
		System.out.println("dayCount=" + dayCount);
	}

7.如何打印当前月份的月历?

	// 打印当前月份的月历
	private static void printMonthCalendar() {
		Calendar calendar = Calendar.getInstance(); // 创建一个日历实例
		calendar.set(Calendar.DATE, 1); // 设置日期为当月1号
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); // 获得该日期对应的星期几
		dayOfWeek = dayOfWeek == 1 ? 7 : dayOfWeek - 1;
		int lastDay = calendar.getActualMaximum(Calendar.DATE); // 获取当月的最后一天
		// 拼接月历开头的年月
		String yearAndMonth = String.format("\n%21s%d年%d月", "",
				calendar.get(calendar.YEAR), calendar.get(calendar.MONTH) + 1);
		System.out.println(yearAndMonth);
		System.out.println(" 星期一 星期二 星期三 星期四 星期五 星期六 星期日");
		for (int i = 1; i < dayOfWeek; i++) { // 先补齐1号前面的空白
			System.out.printf("%7s", "");
		}
		for (int i = 1; i <= lastDay; i++) { // 循环打印从一号到本月最后一天的日子
			String today = String.format("%7d", i);
			System.out.print(today);
			if ((dayOfWeek + i - 1) % 7 == 0) { // 如果当天是星期日,末尾就另起一行
				System.out.println();
			}
		}
	}

在这里插入图片描述

Java8本地日期时间工具

先天不良的Date和后来的Calendar在开发中都存在一定的通病:
1.获取当前月份的时候都是从0开始
2.日历获取星期的时候也是从星期天开始算起的
3.日历获取的最小单位是毫秒,精度不够高,不适合一些科学计算场合
4.日历没有提供判断闰年的方法
5.日历缺乏格式化工具

本地日期类型LocalDate

实例化调用now方法

        LocalDate date = LocalDate.now(); // 获得本地日期的实例
		System.out.println("date=" + date.toString());
		int year = date.getYear(); // 获得该日期所在的年份
		System.out.println("year=" + year);
		// 获得该日期所在的月份。注意getMonthValue返回的是数字月份,getMonth返回的是英文月份
		int month = date.getMonthValue();
		System.out.println("month=" + month + ", english month=" + date.getMonth());
		int dayOfMonth = date.getDayOfMonth(); // 获得该日期所在的日子
		System.out.println("dayOfMonth=" + dayOfMonth);
		int dayOfYear = date.getDayOfYear(); // 获得该日期在一年当中的序号
		System.out.println("dayOfYear=" + dayOfYear);
		// 获得该日期是星期几。注意getDayOfWeek返回的是英文,后面的getValue才返回数字星期几
		int dayOfWeek = date.getDayOfWeek().getValue();
		System.out.println("dayOfWeek=" + dayOfWeek + ", english weekday=" + date.getDayOfWeek());
		int lengthOfYear = date.lengthOfYear(); // 获得该日期所在的年份一共有多少天
		System.out.println("lengthOfYear=" + lengthOfYear);
		int lengthOfMonth = date.lengthOfMonth(); // 获得该日期所在的月份一共有多少天
		System.out.println("lengthOfMonth=" + lengthOfMonth);
		boolean isLeapYear = date.isLeapYear(); // 判断该日期所在的年份是否为闰年
		System.out.println("isLeapYear=" + isLeapYear);

date=2021-07-13
year=2021
month=7, english month=JULY
dayOfMonth=13
dayOfYear=194
dayOfWeek=2, english weekday=TUESDAY
lengthOfYear=365
lengthOfMonth=31
isLeapYear=false

本地时间类型LocalTime

通过本地类型Localtime可以获取本地时间的,也用now方法进行实例化,甚至可以通过getNano方法获得秒钟之后的纳秒单位,代码如下:

		LocalTime time = LocalTime.now(); // 获得本地时间的实例
		System.out.println("time=" + time.toString());
		int hour = time.getHour(); // 获得该时间所在的时钟
		System.out.println("hour=" + hour);
		int minute = time.getMinute(); // 获得该时间所在的分钟
		System.out.println("minute=" + minute);
		int second = time.getSecond(); // 获得该时间所在的秒钟
		System.out.println("second=" + second);
		// 一秒等于一千毫秒,一毫秒等于一千微秒,一微秒等于一千纳秒,算下来一秒等于十亿纳秒
		int nano = time.getNano(); // 获得该时间秒钟后面的纳秒单位
		System.out.println("nano=" + nano);

本地日期时间类型LocalDateTime

        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println("当前日期时间为:" + localDateTime.toString());

当前日期时间为:2021-07-13T14:42:00.520269

实战练习

利用本地日期实现万年历

引用本地日期工具localDate
引入二维数组保存当月的各个星期分布,第一维表示5个星期,第二维表示每个星期的7天

	public static void main(String[] args) {
		showCalendar(2020, 2); // 根据指定年月显示当月的月历
	}

	// 根据指定年月显示当月的月历
	public static void showCalendar(int year, int month) {
		// 行分隔标记
		String line = "\n ————————————————————————————————————————————————————————————————\n";
		String slit = " | "; // 列分隔标记
		String[] weekTitles = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
		LocalDate date = LocalDate.of(year, month, 1); // 获取当月1日的本地日期实例
		// 拼接当前日历的年月标题(包含年份、月份、是否闰年、当月天数等信息)
		String calendar = String.format("\n%20s%d年(%s)%d月(共%d天)%s",
				"", date.getYear(), date.isLeapYear() ? "闰年" : "平年",
				date.getMonthValue(), date.lengthOfMonth(), line);
		String weekTitle = slit; // 月份的星期标题
		// 拼接星期一到星期日的周标题
		for (int i = 0; i < weekTitles.length; i++) {
			weekTitle = String.format("%s%3s%s", weekTitle, weekTitles[i], slit);
		}
		int firstWeekNum = date.getDayOfWeek().getValue(); // 当月第一天是星期几
		int[][] weekdays = new int[5][7]; // 星期的二维数组,每月横跨五个星期
		loop : for (int i = 0; i < 5; i++) { // 遍历组装各个星期
			for (int j = 0; j < 7; j++) { // 通过循环填满星期数组
				if (i==0 && j < firstWeekNum-1) { // 当前日期还是上个月份的日子
					continue; // 不处理,继续下个日期
				} else { // 当前日期位于本月份
					weekdays[i][j] = date.getDayOfMonth(); // 给星期数组填写本月的日期
					if (date.getDayOfMonth() == date.lengthOfMonth()) { // 如果是本月的最后一天
						break loop; // 跳出外层的遍历循环
					} else {
						date = date.plusDays(1); // 日期加一
					}
				}
			}
		}
		String weekDetail = ""; // 月份的星期详情
		for (int i = 0; i < 5; i++) { // 遍历星期的二维数组,把各星期以及分隔串拼接起来
			weekDetail = String.format("%s%s%s", weekDetail, line, slit);
			for (int j = 0; j < 7; j++) { // 拼接本星期的内容,每个日子占据六位空间,且靠右对齐
				if (weekdays[i][j] > 0) { // 属于本月的日期,则填写具体日期
					weekDetail = String.format("%s%6d%s", weekDetail, weekdays[i][j], slit);
				} else { // 不属本月的日期,则留空
					weekDetail = String.format("%s%6s%s", weekDetail, "", slit);
				}
			}
		}
		calendar = String.format("%s%s%s%s", calendar, weekTitle, weekDetail, line);
		System.out.println(calendar); // 打印拼接好的万年历日期
	}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值