加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Calendar 简单实用的日历。add()、set()、roll()方法的区别及官方API说明

(2017-03-14 17:33:44)
标签:

365

分类: java基础

Calendar month 0 开始,也就是全年 12 个月由 0 ~ 11 进行表示。

Calendar.DAY_OF_WEEK 定义和值如下:

Calendar.SUNDAY = 1
Calendar.MONDAY = 2
Calendar.TUESDAY = 3
Calendar.WEDNESDAY = 4
Calendar.THURSDAY = 5
Calendar.FRIDAY = 6
Calendar.SATURDAY = 7

1.   // 创建 Calendar 对象  

2.       Calendar calendar Calendar.getInstance();  

3.     

4.       try  

5.        

6.         //  calendar 设置时间的方法  

7.         // 设置传入的时间格式  

8.         SimpleDateFormat dateFormat new SimpleDateFormat("yyyy-M-d H:m:s");  

9.         // 指定一个日期  

10.      Date date dateFormat.parse("2013-6-1 13:24:16");  

11.      //  calendar 设置为 date 所定的日期  

12.      calendar.setTime(date);  

13.  

14.      // 按特定格式显示刚设置的时间  

15.      str (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS")).format(calendar.getTime());  

16.      System.out.println(str);  

17.     

18.    catch (ParseException e)  

19.     

20.      e.printStackTrace();  

21.     

22.  

23.    // 或者另一種設置 calendar 方式  

24.    // 分別爲 year, month, date, hourOfDay, minute, second  

25.    calendar Calendar.getInstance();  

26.    calendar.set(201312173544);  

27.    str (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS")).format(calendar.getTime());  

28.    System.out.println(str);  

29. // Calendar 取得当前时间的方法  

30.    // 初始化 (重置Calendar 对象  

31.    calendar Calendar.getInstance();  

32.    // 或者用 Date 来初始化 Calendar 对象  

33.    calendar.setTime(new Date());  

34.  

35.    // setTime 类似上面一行  

36.    // Date date new Date();  

37.    // calendar.setTime(date);  

38.  

39.    str (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS")).format(calendar.getTime());  

40.    System.out.println(str);  

41.  

42.    // 显示年份  

43.    int year calendar.get(Calendar.YEAR);  

44.    System.out.println("year is " String.valueOf(year));  

45.  

46.    // 显示月份 (0开始实际显示要加一)  

47.    int month calendar.get(Calendar.MONTH);  

48.    System.out.println("nth is " (month 1));  

49.  

50.    // 本周几  

51.    int week calendar.get(Calendar.DAY_OF_WEEK);  

52.    System.out.println("week is " week);  

53.  

54.    // 今年的第   

55.    int DAY_OF_YEAR calendar.get(Calendar.DAY_OF_YEAR);  

56.    System.out.println("DAY_OF_YEAR is " DAY_OF_YEAR);  

57.  

58.    // 本月第   

59.    int DAY_OF_MONTH calendar.get(Calendar.DAY_OF_MONTH);  

60.    System.out.println("DAY_OF_MONTH " String.valueOf(DAY_OF_MONTH));  

61.  

62.    // 3小时以后  

63.    calendar.add(Calendar.HOUR_OF_DAY, 3);  

64.    int HOUR_OF_DAY calendar.get(Calendar.HOUR_OF_DAY);  

65.    System.out.println("HOUR_OF_DAY " HOUR_OF_DAY);  

66.  

67.    // 当前分钟数  

68.    int MINUTE calendar.get(Calendar.MINUTE);  

69.    System.out.println("MINUTE " MINUTE);  

70.  

71.    // 15 分钟以后  

72.    calendar.add(Calendar.MINUTE, 15);  

73.    MINUTE calendar.get(Calendar.MINUTE);  

74.    System.out.println("MINUTE 15 " MINUTE);  

75.  

76.    // 30分钟前  

77.    calendar.add(Calendar.MINUTE, -30);  

78.    MINUTE calendar.get(Calendar.MINUTE);  

79.    System.out.println("MINUTE 30 " MINUTE);  

80.  

81.    // 格式化显示  

82.    str (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS")).format(calendar.getTime());  

83.    System.out.println(str);  

84.  

85.    // 重置 Calendar 显示当前时间  

86.    calendar.setTime(new Date());  

87.    str (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS")).format(calendar.getTime());  

88.    System.out.println(str);  

89.  

90.    // 创建一个 Calendar 用于比较时间  

91.    Calendar calendarNew Calendar.getInstance();  

92.  

93.    // 设定为 小时以前,后者大,显示 -1  

94.    calendarNew.add(Calendar.HOUR, -5);  

95.    System.out.println("时间比较:" calendarNew.compareTo(calendar));  

96.  

97.    // 设定7小时以后,前者大,显示 1  

98.    calendarNew.add(Calendar.HOUR, +7);  

99.    System.out.println("时间比较:" calendarNew.compareTo(calendar));  

100.    

101.      // 退回 小时,时间相同,显示 0  

102.      calendarNew.add(Calendar.HOUR, -2);  

103.      System.out.println("时间比较:" calendarNew.compareTo(calendar)); 

Add()方法会根据传入的日期和day参数,调整为满足的月份的日期。

Set()会调整到符合day偏移量的日期。

比如 add()set()方法计算后应该得到431号,前者解析打印为430号,后者解析打印为51号。两个方法都能改变日期,但是机制有差异。

在调整月份上Roll()方法 add 相似,比如174月再加13个月,得到的是 175月。

具体原因看官方文档,不管什么时候学什么东西官方文档还是最靠谱的。

注: 对于某些特别时间的解释可能会有某些歧义,可以用下列方式解决:

  1. 23:59 是一天中的最后一分钟,而 00:00 是下一天的第一分钟。因此,1999 12 31 日的 23:59 < 2000 1 1 日的 00:00
  2. 尽管从历史上看不够精确,但午夜也属于 "am",,中午属于 "pm",所以在同一天,12:00 am ( 午夜 ) < 12:01 am12:00 pm ( 中午 ) < 12:01 pm

日期或时间格式字符串不是日历定义的一部分,因为在运行时,用户必须能够修改或重写它们。可以使用 DateFormat 格式化日期。

字段操作

可以使用三种方法更改日历字段:set()add() roll()

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

示例:假定 GregorianCalendar 最初被设置为 1999831 日。调用 set(Calendar.MONTH, Calendar.SEPTEMBER) 将该日期设置为 1999931 日。如果随后调用 getTime(),那么这是解析 1999101 日的一个暂时内部表示。但是,在调用 getTime() 之前调用 set(Calendar.DAY_OF_MONTH, 30) 会将该日期设置为 1999930 日,因为在调用 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 最初被设置为 1999831 日。调用 add(Calendar.MONTH, 13) 将日历设置为 2000930 日。Add 规则 1MONTH 字段设置为 September,因为向August 添加 13 个月得出的就是下一年的September。因为在 GregorianCalendar 中,DAY_OF_MONTH 不可能是 931 日,所以 add 规则 2DAY_OF_MONTH 设置为 30,即最可能的值。尽管它是一个更小的字段,但不能根据规则 2 调整 DAY_OF_WEEK,因为在 GregorianCalendar 中的月份发生变化时,该值也需要发生变化。


roll(f, delta)delta 添加到 f 字段中,但不更改更大的字段。这等同于调用 add(f, delta),但要带以下调整:

Roll 规则。在完成调用后,更大的字段无变化。更大的字段表示一个更大的时间单元。DAY_OF_MONTH 是一个比 HOUR 大的字段。

示例:请参阅 GregorianCalendar.roll(int, int)

使用模型。为了帮助理解 add()roll() 的行为,假定有一个用户界面组件,它带有用于月、日、年和底层 GregorianCalendar 的递增或递减按钮。如果从界面上读取的日期为 1999131 日,并且用户按下月份的递增按钮,那么应该得到什么?如果底层实现使用 set(),那么可以将该日期读为 199933 日。更好的结果是 1999228 日。此外,如果用户再次按下月份的递增按钮,那么该日期应该读为 1999331 日,而不是 1999328 日。通过保存原始日期并使用 add()roll(),根据是否会影响更大的字段,用户界面可以像大多数用户所期望的那样运行。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有