说起java中的时间,大家或许都很熟悉,朗朗上口的Date、Calendar、SimpleDateFormat等。但是大家对他们的认识真的很深刻吗?我要想大家说的是TimeZone,即时区。

  经常有人发现时间不对,比如相差8个小时等等,其真实原因便是TimeZone。只有正确合理的运用TimeZone,才能保证系统时间无论何时都是准确的。

  影响TimeZone的因素:

  1、操作系统的时区设置。

  2、数据传输时时区设置。

  第一个原因其实是根本原因,当数据在不同操作系统间流转时,有可能因为操作系统的差异造成时间偏差,而JVM默认情况下获取的是操作系统的时区设置。因此在项目中好事先设置好时区,例如:

TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));

  那么一旦时区设置不同导致时间有偏差怎么办?如何转化呢?

  ● 用SimpleDateFormat的话,如下:

 public static void main(String[] args) {
  Date date = new Date(1359641834000L);// 2013-1-31 22:17:14
  String dateStr = "2013-1-31 22:17:14";
  SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
  try {
   Date dateTmp = dateFormat.parse(dateStr);
   System.out.println(dateTmp);
  } catch (ParseException e) {
   e.printStackTrace();
  }
  String dateStrTmp = dateFormat.format(date);
  System.out.println(dateStrTmp);
 }

  运行结果:

Fri Feb 01 06:17:14 CST 2013
2013-01-31 14:17:14

  我们发现同一时间,字符串和日期运行出来的结果并不相同,那么我们应该怎么理解呢?一切都要以当前操作系统的时间为基准。我的操作系统是"Asia/Shanghai",即GMT+8的北京时间,那么执行日期转字符串的format方法时,由于日期生成时默认是操作系统时区,因此2013-1-31 22:17:14是北京时间,那么推算到GMT时区,自然是要减8个小时的;而执行字符串转日期的parse方法时,由于字符串本身没有时区的概念,因此2013-1-31 22:17:14是指GMT(UTC)时间【ps:所有字符串都看做是GMT时间】,那么当转化为日期时要加上默认时区,即"Asia/Shanghai",因此要加上8个小时。

  ● 用Calendar的话,如下:

 public static void main(String[] args) {
  Date date = new Date(1359641834000L);// 2013-1-31 22:17:14
  System.out.println(date);
  Calendar calendar = Calendar.getInstance();
  calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
  // 或者可以 Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
  calendar.setTime(date);
  System.out.println(calendar.get(Calendar.HOUR_OF_DAY) + ":" + calendar.get(Calendar.MINUTE));
 }

  运行结果:

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