搜索
首页Javajava教程对Calendar的概述

对Calendar的概述

Jul 23, 2017 am 10:22 AM
java基础

1、Calendar概述

  Java官方推荐使用Calendar来替换Date的使用,Calendar与Date之间可以自由的进行转换,转换的纽带是time,使用Calendar的getTime()方法可以得到一个Date类型的对象,这个对象底层是使用Date的第二个带Long型参数的构造器创建的,这个Long型参数是Calendar中的time字段中保存的值,这个time字段的值是在具体的实现类中定义赋值的比如GregorianCalendar中的实现computeTime(),这个方法的目的就是将field值转换为time值,这个涉及到Calendar中的两种模式,之后会有介绍;而通过Calendar的setTime(Date date)方法可以将一个Date对象转换为一个Calendar对象,这个方法以一个Date对象为参数,底层调用的setTimeInMillis(long millis)方法,将date.getTime()的值作为参数,再底层会将这个Long型参数值赋值给time字段,这时会重计算field值。

  Calendar与Date的转换

 1     public static void main(String[] args) { 2         //Calendar--->Date 3         Calendar c = Calendar.getInstance(); 4         Date d = c.getTime(); 5         //Date--->Calendar 6         Date d1 = new Date(); 7         Calendar c1 = Calendar.getInstance(); 8         c1.setTime(d1); 9         10         System.out.println(d);11         System.out.println(c1.get(Calendar.YEAR)+"年"+(c1.get(Calendar.MONTH)+1)+"月"+c1.get(Calendar.DATE)+"日");12     }

结果:

Sat Jul 08 10:39:14 CST 20172017年7月8日

2、Calendar中的time与field

  Calendar中有两种描述时间内容的域,一种就是time,它用来保存Calendar对象所代表的时间点据1970年1月1日 00:00:00的毫秒数,另一种就是field,它是一个数组,它表示的并不是一个内容,而是Calendar内部定义的最多静态常量字段。

  而这一般情况下是同步的,即表述的是同一时间点,但也有可能会出现不同步的情况:

  a、起初,field没有设置,time也是无效的

  b、如果time被设置,所有的field都会自动被设置为同步的时间点

  c、如果某一field被单独设置,time会自动失效

  更确切的说,当我们通过Calendar.getInstance()方法获取一个全新的Calendar对象时,它所代表的时间点是通过time来设置的,而这个time的值是通过System.currentTimeMillis()得到的,通过time定义Calendar,isTimeSet为true,表示time值是最新的(真的),areFieldsSet为false,表示field字段的值都是旧的(假的),因为当我们重新设置了time值之后,Calendar所代表的时间点就发生了变化(这里是首次,相当于从无到有,也算是变化,之后当我们为Calendar的time重新设置一个新值时,Calendar的时间点就会再次发生变化,它会指向最新的time值所代表的时间点),而这时field中还表示的是原来的时间点内容,然后会调用computeFields()方法进行所有字段值的重计算,确保field中的值与time同步,并同时将areFieldsSet和areAllFieldsSet设置为true,表示所有的field代表的时间值也是最新的了(真)。其实我们每次更改time值都会自动触发重计算,来确保两个域所描述的时间点一致(即同步),这也就是上面b所述的内容。

  但是如果我们通过set(int field, int value)单独对field中的某行一字段进行更改时,首先会触发一个验证,areFieldsSet为真而areAllFieldsSet为false时,表示只有一部分field是最新的情况,即存在部分field属于旧的情况,针对这种情况会触发field的重新计算;之后会将isTimeSet设置为false,areFieldsSet设置为false,将isSet[field]设置为true(将当前field设置为真),这种情况下,当我们使用getTime()获取time值所代表的时间点时,由于isTimeSet为false,会触发time的重计算,这个计算依据是根据field的值进行的,之后将isTimeSet设置为true,同样我们在通过get(int field)获取某个field值时也会先验证isTimeSet是否为true,如果为false,同样会触发time的重计算,然后验证areFieldsSet为false,则触发其余field的重计算。

  time的重计算是依据field的,确切的说是依据部分field的,而有一部分field也是在field的基础上再计算的,所以可以说有一部分field是固定的,是和time息息相关的,

  以上种种所述全部是Calendar内部的实现规则,对外而言,我们只需要简单的调用即可,所有这些都被隐藏在内部,从而保证我们通过对外方法获取到的直接就是正确的值。

 1     public static void main(String[] args) throws ParseException { 2         System.out.println("-------初始情况-------"); 3         Calendar c = Calendar.getInstance(); 4         System.out.println(c.getTime()); 5         System.out.println(c.get(Calendar.DATE)); 6         System.out.println(c.get(Calendar.HOUR)); 7         System.out.println("-------重设置time-------"); 8         c.setTime(new SimpleDateFormat("yyyyMMdd").parse("20170501")); 9         System.out.println(c.getTime());10         System.out.println(c.get(Calendar.DATE));11         System.out.println(c.get(Calendar.HOUR));12         System.out.println("-------重设置field-------");13         c.set(Calendar.MONTH, 4);14         System.out.println(c.getTime());15         System.out.println(c.get(Calendar.DATE));16         System.out.println(c.get(Calendar.HOUR));17         System.out.println("总结:time与field所代表时间点同步,所有的不同步全部在内部处理完成");18     }

结果:

-------初始情况-------Sat Jul 08 13:08:34 CST 2017
8
1
-------重设置time-------Mon May 01 00:00:00 CST 2017
1
0
-------重设置field-------Mon May 01 00:00:00 CST 2017
1
0总结:time与field所代表时间点同步,所有的不同步全部在内部处理完成

3、Calendar中的两种解析模式

  lenient:该模式下可以自动规则化用户赋值给Calendar的不规则值,比如1月32日会被解析为2月1日

  non-lenient:该模式下不会自动解析不规则的输入,而是一旦发现不规则输入,就会报出异常

  这也叫Calendar的容错性,lenient的开启与关闭使用setLenient(boolean lenient)方法来设置,true表示开启容错性(默认情况),false表示关闭该功能。

 1     public static void main(String[] args) { 2         Calendar c = Calendar.getInstance(); 3         c.set(Calendar.MONTH, 8); 4         c.set(Calendar.DAY_OF_MONTH, 33); 5         System.out.println(c.getTime()+"\n"); 6         c.setLenient(false); 7         c.set(Calendar.MONTH, 8); 8         c.set(Calendar.DAY_OF_MONTH, 33); 9         System.out.println(c.getTime());10     }

结果:

Tue Oct 03 13:18:48 CST 2017Exception in thread "main" java.lang.IllegalArgumentException: DAY_OF_MONTH
    at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2583)
    at java.util.Calendar.updateTime(Calendar.java:2606)
    at java.util.Calendar.getTimeInMillis(Calendar.java:1118)
    at java.util.Calendar.getTime(Calendar.java:1091)
    at JdkTest.main(JdkTest.java:87)

  从上面的例子中可以看出,默认情况下,我们为Calendar的月份赋值为8即九月份,日期赋值为33即下一月3号,输出为10月3日,容错性将这种不符合规则的输入规则化处理了,而关闭容错性之后,同样的赋值只会报异常java.lang.IllegalArgumentException(非法参数异常)。

4、Calendar的使用

 1     public static void main(String[] args) throws ParseException { 2         //通过SimpleDateFormat解析日期字符串 3         SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hh:mm:ss.SSS"); 4         Date date = sdf.parse("20170502 13:33:23.433"); 5         //将Date格式日期转换成Calendar 6         Calendar c = Calendar.getInstance(); 7         c.setTime(date); 8         //获取时间值 9         System.out.println(c.getTime());10         System.out.println("年份为"+c.get(Calendar.YEAR));11         System.out.println("月份为"+c.get(Calendar.MONTH));12         System.out.println("日期为"+c.get(Calendar.DATE));13         System.out.println("日期为"+c.get(Calendar.DAY_OF_MONTH));14         System.out.println("日期为"+c.get(Calendar.DAY_OF_WEEK));15         System.out.println("日期为"+c.get(Calendar.DAY_OF_WEEK_IN_MONTH));16         System.out.println("日期为"+c.get(Calendar.DAY_OF_YEAR));17         System.out.println("时为"+c.get(Calendar.HOUR));18         System.out.println("时为"+c.get(Calendar.HOUR_OF_DAY));19         System.out.println("分为"+c.get(Calendar.MINUTE));20         System.out.println("秒为"+c.get(Calendar.SECOND));21         System.out.println("毫秒为"+c.get(Calendar.MILLISECOND));22         System.out.println("星期为"+c.get(Calendar.WEEK_OF_MONTH));23         System.out.println("星期为"+c.get(Calendar.WEEK_OF_YEAR));24         System.out.println("历型为"+c.get(Calendar.ERA));25         System.out.println("zone为"+c.get(Calendar.ZONE_OFFSET));26         //设置27         c.set(Calendar.MONTH, Calendar.APRIL);28         System.out.println("修改后月份为"+c.get(Calendar.MONTH));29         c.set(1999, 0, 23);30         System.out.println(c.getTime());31         c.set(2000, 1, 12, 13, 33, 14);32         System.out.println(c.getTime());33         c.set(2001, 2, 13, 14, 13);34         System.out.println(c.getTime());35         //运算36         System.out.println("-----运算-----");37         c.add(Calendar.YEAR, 12);38         System.out.println(c.getTime());39         c.add(Calendar.MONTH, -1);40         System.out.println(c.getTime());41         c.roll(Calendar.DATE, true);42         System.out.println(c.getTime());43         c.add(Calendar.DATE, 1);44         System.out.println(c.getTime());45         //roll与add运算对比46         c.set(2000, 1, 29);47         System.out.println(c.getTime());48         c.roll(Calendar.DATE, 1);49         System.out.println(c.getTime());50         c.set(2000, 1, 29);51         c.add(Calendar.DATE, 1);52         System.out.println(c.getTime());53     }

结果:

Tue May 02 13:33:23 CST 2017年份为2017
月份为4
日期为2
日期为2
日期为3
日期为1
日期为122
时为1
时为13
分为33
秒为23
毫秒为433
星期为1
星期为18
历型为1
zone为28800000
修改后月份为3
Sat Jan 23 13:33:23 CST 1999Sat Feb 12 13:33:14 CST 2000Tue Mar 13 14:13:14 CST 2001
-----运算-----Wed Mar 13 14:13:14 CST 2013Wed Feb 13 14:13:14 CST 2013Thu Feb 14 14:13:14 CST 2013Fri Feb 15 14:13:14 CST 2013Tue Feb 29 14:13:14 CST 2000Tue Feb 01 14:13:14 CST 2000Wed Mar 01 14:13:14 CST 2000

  对比上面最后的两行输出,可以看出add与roll的运算规则其实是不同的,roll的运算不会影响大规则(这里的大规则指的是月份的改变)的改变,而add会影响。 

以上是对Calendar的概述的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
JVM中的类加载程序子系统如何促进平台独立性?JVM中的类加载程序子系统如何促进平台独立性?Apr 23, 2025 am 12:14 AM

类加载器通过统一的类文件格式、动态加载、双亲委派模型和平台无关的字节码,确保Java程序在不同平台上的一致性和兼容性,实现平台独立性。

Java编译器会产生特定于平台的代码吗?解释。Java编译器会产生特定于平台的代码吗?解释。Apr 23, 2025 am 12:09 AM

Java编译器生成的代码是平台无关的,但最终执行的代码是平台特定的。1.Java源代码编译成平台无关的字节码。2.JVM将字节码转换为特定平台的机器码,确保跨平台运行但性能可能不同。

JVM如何处理不同操作系统的多线程?JVM如何处理不同操作系统的多线程?Apr 23, 2025 am 12:07 AM

多线程在现代编程中重要,因为它能提高程序的响应性和资源利用率,并处理复杂的并发任务。JVM通过线程映射、调度机制和同步锁机制,在不同操作系统上确保多线程的一致性和高效性。

在Java的背景下,'平台独立性”意味着什么?在Java的背景下,'平台独立性”意味着什么?Apr 23, 2025 am 12:05 AM

Java的平台独立性是指编写的代码可以在任何安装了JVM的平台上运行,无需修改。1)Java源代码编译成字节码,2)字节码由JVM解释执行,3)JVM提供内存管理和垃圾回收功能,确保程序在不同操作系统上运行。

Java应用程序仍然可以遇到平台特定的错误或问题吗?Java应用程序仍然可以遇到平台特定的错误或问题吗?Apr 23, 2025 am 12:03 AM

Javaapplicationscanindeedencounterplatform-specificissuesdespitetheJVM'sabstraction.Reasonsinclude:1)Nativecodeandlibraries,2)Operatingsystemdifferences,3)JVMimplementationvariations,and4)Hardwaredependencies.Tomitigatethese,developersshould:1)Conduc

云计算如何影响Java平台独立性的重要性?云计算如何影响Java平台独立性的重要性?Apr 22, 2025 pm 07:05 PM

云计算显着提升了Java的平台独立性。 1)Java代码编译为字节码,由JVM在不同操作系统上执行,确保跨平台运行。 2)使用Docker和Kubernetes部署Java应用,提高可移植性和可扩展性。

Java的平台独立性在广泛采用中扮演着什么角色?Java的平台独立性在广泛采用中扮演着什么角色?Apr 22, 2025 pm 06:53 PM

Java'splatformindependenceallowsdeveloperstowritecodeonceandrunitonanydeviceorOSwithaJVM.Thisisachievedthroughcompilingtobytecode,whichtheJVMinterpretsorcompilesatruntime.ThisfeaturehassignificantlyboostedJava'sadoptionduetocross-platformdeployment,s

容器化技术(例如Docker)如何影响Java平台独立性的重要性?容器化技术(例如Docker)如何影响Java平台独立性的重要性?Apr 22, 2025 pm 06:49 PM

容器化技术如Docker增强而非替代Java的平台独立性。1)确保跨环境的一致性,2)管理依赖性,包括特定JVM版本,3)简化部署过程,使Java应用更具适应性和易管理性。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)