Java: 日期相关的类 XMLGregorianCalendar 和 GregorianCalendar
2013-11-23 19:00
906 查看
在 Web 开发中经常需要操纵 Web Service 的响应的信息,其中可能包含日期信息。如果开发是基于 Java 的,通常可以通过返回 XMLGregorianCalendar 类的一个对象来表示一个时间,该对象封装了一个具体时间的年、月、日、时、分、秒及时区(Time Zone)信息。我们假设通过以下语句获取了一个 XMLGregorianCalendar 对象:
如果在业务上需要将该时间和系统当前时间做比较,由于 XMLGregorianCalendar 类同 GregorianCalendar 类有方便的接口进行转换,我们通常可以创建一个 GregorianCalendar 的对象以捕捉当前系统时间。如下:
现在的问题是:如何比较这两个时间对象(xcStartTime 和 gcCurrTime)的先后关系呢?
方法一、
熟悉接口的程序员可以先调用 XMLGregorianCalendar 类的 toGregorianCalendar 方法,将 XMLGregorianCalendar 类的对象转化为 GregorianCalendar 的对象;
然后基于 GregorianCalendar 类的接口来比较两个 GregorianCalendar 对象:
最简单的方式:
方法二、
可以转为整数表示的毫秒,然后比较;
方法三、
上面的方法可以直接通过一个函数 compareTo 来实现:该函数比较两个 GregorianCalendar 对象的从1970年1月1日UTC时间00:00起始的毫秒数,如果相等,返回 0;否则,返回负数或正数。
方法四、
人工转换需要注意的问题。有如下代码:
编译运行结果如下:
上述结果分别是1月31日和3月3日,注意到月份信息和日期信息均是不正确的。
考察了一下这两个类,首先是 XMLGregorianCalendar:
为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。
参数:
有如下的程序:
编译运行结果为:
可以看出,结果已经是正确的。
延伸:
GregorianCalendar 类可以通过 getTime () 返回一个 Date 对象, Date 类也提供了诸如 boolean before ()、boolean after ()、 int compareTo ()、long getTime() 等方法用于比较时间。
注意:
Date 类的月份信息也是由 0~11 表示的。以下来自JavaSE6的中文API:
最后:
JDK的日期和时间信息尽量使用 Calendar 类,该类提供了更丰富的接口,GregorianCalendar 类的上述方法都是继承该类的(当然其中的月份也是使用0表示每年的一月)。使用该类可以方便地比较时间。
// 假设函数 func() 返回一个 XMLGregorianCalendar 对象 XMLGregorianCalendar xcStartTime = func ();
如果在业务上需要将该时间和系统当前时间做比较,由于 XMLGregorianCalendar 类同 GregorianCalendar 类有方便的接口进行转换,我们通常可以创建一个 GregorianCalendar 的对象以捕捉当前系统时间。如下:
// 创建一个 GregorianCalendar 对象表示系统当前时间 GregorianCalendar gcCurrTime = new GregorianCalendar ();
现在的问题是:如何比较这两个时间对象(xcStartTime 和 gcCurrTime)的先后关系呢?
方法一、
熟悉接口的程序员可以先调用 XMLGregorianCalendar 类的 toGregorianCalendar 方法,将 XMLGregorianCalendar 类的对象转化为 GregorianCalendar 的对象;
// 将 XMLGregoriancalendar 类的对象转为 GregorianCalendar 类的对象。 GregorianCalendar gcStartTime = xcStartTime.toGregorianCalendar ();
然后基于 GregorianCalendar 类的接口来比较两个 GregorianCalendar 对象:
最简单的方式:
// 使用 before 或 after 接口 if (gcStartTime.before (gcCurrTime)){ // TODO: } else{ // TODO: }
方法二、
可以转为整数表示的毫秒,然后比较;
//先获取时间对象的毫秒值(从1970年1月1日00:00起始的 UTC 时间开始计数的毫秒数) long lnStartTime = gcStartTime.getTimeInMillis (); long lnCurrtTime = gcStartTime.getTimeInMillis (); //然后比较这两个整数 if (lnStartTime > lnCurrtTime){ // TODO: } else{ // TODO: }
方法三、
上面的方法可以直接通过一个函数 compareTo 来实现:该函数比较两个 GregorianCalendar 对象的从1970年1月1日UTC时间00:00起始的毫秒数,如果相等,返回 0;否则,返回负数或正数。
int ret = gcCurrTime.compareTo (gcStartTime); if (ret == 0){ // TODO: } if (ret < 0){ // TODO: } if (ret > 0){ // TODO: }
方法四、
人工转换需要注意的问题。有如下代码:
import java.util.Date; import java.util.GregorianCalendar; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; public class A { public static void main(String[] args) throws Exception { // 创建一个 XMLGregorianCalendar 对象表示 1999年1月31日18时30分59秒999毫秒,时区信息为0的时间 XMLGregorianCalendar xt = DatatypeFactory.newInstance().newXMLGregorianCalendar(1999, 1, 31, 18, 30, 59, 999, 0); // 创建一个 GregorianCalendar 对象,依次取出上述对象的信息填入其中 GregorianCalendar gt = new GregorianCalendar(xt.getYear(), xt.getMonth(), xt.getDay(), xt.getHour(), xt.getMinute(), xt.getSecond()); // 返回 GregorianCalendar 类对象 gt 的一个 Date 对象,以方便打印 Date date = gt.getTime(); System.out.println(xt); System.out.println(date); } }
编译运行结果如下:
1999-01-31T18:30:59.999Z Wed Mar 03 18:30:59 CST 1999
上述结果分别是1月31日和3月3日,注意到月份信息和日期信息均是不正确的。
考察了一下这两个类,首先是 XMLGregorianCalendar:
然后 GregorianCalendar
public GregorianCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second)
为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。
参数:
year- 用来在日历中设置
YEAR日历字段的值。
month- 用来在日历中设置
MONTH日历字段的值。Month 值是基于 0 的,例如,0 表示 1 月。
dayOfMonth- 用来在日历中设置
DAY_OF_MONTH日历字段的值。
hourOfDay- 用来在日历中设置
HOUR_OF_DAY日历字段的值。
minute- 用来在日历中设置
MINUTE日历字段的值。
second- 用来在日历中设置
SECOND日历字段的值。从上面的文档可以看出。这两个类对月份信息的处理是不一样的:XMLGregorianCalendar 使用1~12表示月份,而 GregorianCalendar 使用0~11表示月份,所以从 XMLGregorianCalendar 到 GregorianCalendar 的转换,需要将月份数值减去1。
有如下的程序:
import java.util.Date; import java.util.GregorianCalendar; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; public class A { public static void main(String[] args) throws Exception { // 创建一个 XMLGregorianCalendar 对象表示 1999年1月31日18时30分59秒999毫秒,时区信息为0的时间 XMLGregorianCalendar xt = DatatypeFactory.newInstance().newXMLGregorianCalendar(1999, 1, 31, 18, 30, 59, 999, 0); // 创建一个 GregorianCalendar 对象,依次取出上述对象的信息填入其中 GregorianCalendar gt = new GregorianCalendar(xt.getYear(), xt.getMonth() - 1, xt.getDay(), xt.getHour(), xt.getMinute(), xt.getSecond()); // 返回 GregorianCalendar 类对象 gt 的一个 Date 对象,以方便打印 Date date = gt.getTime(); System.out.println(xt); System.out.println(date); } }
编译运行结果为:
1999-01-31T18:30:59.999Z Sun Jan 31 18:30:59 CST 1999
可以看出,结果已经是正确的。
延伸:
GregorianCalendar 类可以通过 getTime () 返回一个 Date 对象, Date 类也提供了诸如 boolean before ()、boolean after ()、 int compareTo ()、long getTime() 等方法用于比较时间。
注意:
Date 类的月份信息也是由 0~11 表示的。以下来自JavaSE6的中文API:
最后:
JDK的日期和时间信息尽量使用 Calendar 类,该类提供了更丰富的接口,GregorianCalendar 类的上述方法都是继承该类的(当然其中的月份也是使用0表示每年的一月)。使用该类可以方便地比较时间。
相关文章推荐
- Java: 日期相关的类 XMLGregorianCalendar 和 GregorianCalendar
- XMLGregorianCalendar日期类型与Date(java.util.*)日期类型之间相互转换
- XMLGregorianCalendar和java.util.Date的相互转化
- 使用java.util.Calendar来取得相关日期信息
- Java WebService把Date类型转换成XMLGregorianCalendar
- freemarker XMLGregorianCalendar 转日期
- CXF全接触(八) --- 使用wsdl2java时转换XMLGregorianCalendar为Date
- Java WebService把Date类型转换成XMLGregorianCalendar
- java日期处理类总结:Date/Calendar/GregorianCalendar/DateFormat/SimpleDateFormat类
- java:日期相关Date,Calendar,SimpleDateFormat
- Java API的Date, Calendar日期处理相关类分析
- java.lang.NoClassDefFoundError: org/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl$DaysInMonth
- java 日期相关Date、SimpleDateFormat、Calendar区分和使用
- Java -- 键盘输入 Scanner, BufferedReader。 系统相关System,Runtime。随机数 Randrom。日期操作Calendar
- Java的XMLGregorianCalendar和Date及String相互转换
- Java -- 键盘输入 Scanner, BufferedReader。 系统相关System,Runtime。随机数 Randrom。日期操作Calendar
- java API 跟时间相关类:Date/Calendar/GregorianCalendar/DateFormat/SimpleDateFormat
- 错误修复:java.lang.NoClassDefFoundError: org/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl$Parser
- java日期格式化及获取相关总结
- XMLGregorianCalendar和Date之间的转换