博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Calendar类
阅读量:5952 次
发布时间:2019-06-19

本文共 4726 字,大约阅读时间需要 15 分钟。

接触java不久,感觉java真的挺好玩的。

Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEARMONTHDAY_OF_MONTHHOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。

在书上看到一个挺好玩的代码,通过这个代码浅浅的研究了下java中的Calendar类

输出的结果是:

PS:为了学习和理解方便,我将时间调回2011年,因为2012年刚好1月1号刚好是周日。

字段操作:

三种:set(),add(),roll();

set(f, value) 将日历字段 f 更改为 value。此外,它设置了一个内部成员变量,以指示日历字段 f 已经被更改。尽管日历字段 f 是立即更改的,但是直到下次调用 get()getTime()getTimeInMillis()add()roll() 时才会重新计算日历的时间值(以毫秒为单位)。因此,多次调用 set() 不会触发多次不必要的计算。使用 set() 更改日历字段的结果是,其他日历字段也可能发生更改,这取决于日历字段、日历字段值和日历系统。此外,在重新计算日历字段之后,get(f) 没必要通过调用 set 方法返回 value 集合。具体细节是通过具体的日历类确定的。

 

示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 set(Calendar.MONTH, Calendar.SEPTEMBER) 将该日期设置为 1999 年 9 月 31 日。如果随后调用 getTime(),那么这是解析 1999 年 10 月 1 日的一个暂时内部表示。但是,在调用 getTime() 之前调用 set(Calendar.DAY_OF_MONTH, 30) 会将该日期设置为 1999 年 9 月 30 日,因为在调用 set() 之后没有发生重新计算。

 

  个人建议先跳过规则看下示例,然后再回过来理解。

add(f, delta)delta 添加到 f 字段中。这等同于调用 set(f, get(f) + delta),但要带以下两个调整:

  Add 规则 1。调用后 f 字段的值减去调用前 f 字段的值等于 delta,以字段 f 中发生的任何溢出为模。溢出发生在字段值超出其范围时,结果,下一个更大的字段会递增或递减,并将字段值调整回其范围内。

  Add 规则 2。如果期望某一个更小的字段是不变的,但让它等于以前的值是不可能的,因为在字段 f 发生更改之后,或者在出现其他约束之后,比如时区偏移量发生更改,它的最大值和最小值也在发生更改,然后它的值被调整为尽量接近于所期望的值。更小的字段表示一个更小的时间单元。HOUR 是一个比 DAY_OF_MONTH 小的字段。对于不期望是不变字段的更小字段,无需进行任何调整。日历系统会确定期望不变的那些字段。

此外,与 set() 不同,add() 强迫日历系统立即重新计算日历的毫秒数和所有字段。

 

示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 add(Calendar.MONTH, 13) 将日历设置为 2000 年 9 月 30 日。Add 规则 1MONTH 字段设置为 September,因为向 August 添加 13 个月得出的就是下一年的 September。因为在 GregorianCalendar 中,DAY_OF_MONTH 不可能是 9 月 31 日,所以 add 规则 2DAY_OF_MONTH 设置为 30,即最可能的值。尽管它是一个更小的字段,但不能根据规则 2 调整 DAY_OF_WEEK,因为在 GregorianCalendar 中的月份发生变化时,该值也需要发生变化。

 

以下是代码,书上的代码及注释+我自己的理解和调试观察。

import java.text.DateFormatSymbols; import java.util.*; /**  * @version 1.4 2007-04-07  * @author Cay Horstmann */ public class CalendarTest {
public static void main(String[] args) {
// construct d as current date //GregorianCalendar 是 Calendar 的一个具体子类,提供了世界上大多数国家/地区使用的标准日历系统。 //用来表示默认地区。默认时区的当前时间。 GregorianCalendar d = new GregorianCalendar(); int today = d.get(Calendar.DAY_OF_MONTH); int month = d.get(Calendar.MONTH);//0为第一个月 //以下一段代码是测试,类里面的一些方法,测试娱乐。 /* * int hour = d.get(Calendar.HOUR_OF_DAY);//0~23 * int minute = d.get(Calendar.MINUTE); //0~59 * int second = d.get(Calendar.SECOND); //0~59 * System.out.println(month+1+"月"+today+"日"+hour+"时"+minute+"分"+second+"秒"); */ // set d to start date of the month d.set(Calendar.DAY_OF_MONTH, 1); //Sunday==1; 1<=weekday<=7; int weekday = d.get(Calendar.DAY_OF_WEEK); //因为是周六,所以weekday == 7; //System.out.println(weekday); // get first day of week (Sunday in the U.S.) int firstDayOfWeek = d.getFirstDayOfWeek(); //firstDayOfWeek==1; // determine the required indentation for the first line int indent = 0; //一周的第一天是否是月的第一天,如果不是,则追溯到上个月找到这个周的第一天所在的时间。 while (weekday != firstDayOfWeek) {
indent++; d.add(Calendar.DAY_OF_MONTH, -1); weekday = d.get(Calendar.DAY_OF_WEEK); //int temp=d.get(Calendar.DAY_OF_MONTH); //System.out.println(temp); } /* * DateFormatSymbols 是用于压缩本地化的日期_时间格式化数据,如月份名称、星期名称和时区数据的公有类。 * * public String[] getShortWeekdays() * 获得短型工作日字符串。 例如:"Sun", "Mon" 等。 * 返回值:短型工作日字符串。 */ // print weekday names String[] weekdayNames = new DateFormatSymbols().getShortWeekdays(); /* * 以下循环操作类似于这个,但是前面一系列操作用于确定第一天是从周几开始(因地区而异)。所以不用我下面这两行程序 * for(int i=1; i<=7; i++) * System.out.printf("%s", weekdayNames[i]); * * 此时:weekday == firstDayOfWeek * 但地下循环为先执行后判断,即从周的选定的第一天 开始循环7次 */ do {
System.out.printf("%4s", weekdayNames[weekday]); d.add(Calendar.DAY_OF_MONTH, 1); weekday = d.get(Calendar.DAY_OF_WEEK); }while (weekday != firstDayOfWeek); System.out.println(); //月的1号一般不是从周的第一天开始。比如:周的第一天是周日,而2011年的第一天是周六,空出前6天的位置。 for (int i = 1; i <= indent; i++) System.out.print(" "); d.set(Calendar.DAY_OF_MONTH, 1); do {
// print day int day = d.get(Calendar.DAY_OF_MONTH); System.out.printf("%3d", day); // mark current day with * if (day == today) System.out.print("*"); else System.out.print(" "); // advance d to the next day d.add(Calendar.DAY_OF_MONTH, 1); weekday = d.get(Calendar.DAY_OF_WEEK); // start a new line at the start of the week if (weekday == firstDayOfWeek) System.out.println(); }while (d.get(Calendar.MONTH) == month); // the loop exits when d is day 1 of the next month // print final end of line if necessary if (weekday != firstDayOfWeek) System.out.println(); } }

 

 

 

转载于:https://www.cnblogs.com/FreeAquar/archive/2012/01/17/2325069.html

你可能感兴趣的文章
46.tornado绑定域名或者子域名泛域名的处理
查看>>
文本过滤--sed 1
查看>>
PHP CURL并发,多线程
查看>>
ES 概念及动态索引结构和索引更新机制
查看>>
iOS 开发百问(2)
查看>>
MySQL for Mac 安装和基本操作(包含后期的环境变量设置)
查看>>
Linux及windows下常见压缩程序的压缩能力对比
查看>>
JAVAEE-junit测试hibernate里的方法(hibernate交给spring管理)的问题
查看>>
MOTO MB860 国行2.3.5优化增强ROM_Top_T5_end(经典收藏版)
查看>>
C#学习经典(二)---MVC框架(Model view Controller)
查看>>
log4j配置文件说明
查看>>
Maven: 为Compiler插件设置source和target版本
查看>>
linux下永久添加静态路由
查看>>
android 全局变量和局部变量命名规则
查看>>
Ubuntu Sub-process /usr/bin/dpkg
查看>>
详解DNS的常用记录(下):DNS系列之三
查看>>
linux的日志服务器关于屏蔽一些关键字的方法
查看>>
事情的两面性
查看>>
只要会营销,shi都能卖出去?
查看>>
sed单行处理命令奇偶行输出
查看>>