Calendar不涉及到日期与字符串的转化,因此不像SimpleDateFormat那么复杂,与日期转字符串的思路类似。但是需要注意的是,设置完时区后,我们不能用calendar.getTime()来直接获取Date日期,因此此时的日期与一开始setTime时是相同值,要想获取某时区的时间,正确的做法是用calendar.get()方法,那么我们怎么获得Date类型的日期呢?

  正确的做法如下:

 public static void main(String[] args) {
  Date date = new Date(1359641834000L);
  System.out.println(date);
  Calendar calendar = Calendar.getInstance();
  calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
  // 或者可以 Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
  calendar.setTime(date);
  Calendar calendar2 = Calendar.getInstance();
  calendar2.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
  System.out.println(calendar2.getTime());
 }

  运行结果:

Thu Jan 31 22:17:14 CST 2013
Thu Jan 31 14:17:14 CST 2013

  ● 完美通用转换方法

  其实上面两个转换方法都要受到操作系统的时区设置影响,如果软件在不同操作系统运行,仍然会有时间误差,那么怎么才能统一呢?

 public static void main(String[] args) {
  Date date = new Date(1359641834000L);
  System.out.println(date);
  date = changeTimeZone(date, TimeZone.getTimeZone("Asia/Shanghai"), TimeZone.getTimeZone("GMT"));
  System.out.println(date);
 }
 
 /**
  * 获取更改时区后的日期
  * @param date 日期
  * @param oldZone 旧时区对象
  * @param newZone 新时区对象
  * @return 日期
  */
 public static Date changeTimeZone(Date date, TimeZone oldZone, TimeZone newZone) {
  Date dateTmp = null;
  if (date != null) {
   int timeOffset = oldZone.getRawOffset() - newZone.getRawOffset();
   dateTmp = new Date(date.getTime() - timeOffset);
  }
  return dateTmp;
 }

  运行结果:

Thu Jan 31 22:17:14 CST 2013
Thu Jan 31 14:17:14 CST 2013

  通过以上可以看出时区确实有不少需要我们注意和专研的地方,其实这并不是什么高深的东西,也是java日期里的基础,我认为盲目学习各种开源框架并不能成为真正的高手,框架也是基于jdk的基础上开发而来的,不懂jdk的基本知识,想真正提高到架构师的级别是非常苦难的,因此基础很重要,掌握jdk基本功确实是成为“大侠”的前提条件,共同努力吧!