java对世界各个时区(TimeZone)的通用转换处理方法

2008 - 10 - 31

java对世界各个时区(TimeZone)的通用转换处理方法

关键字: java 世界时区转换 timezone
★★★ 本篇为原创,需要引用转载的朋友请注明:《 http://stephen830.javaeye.com/blog/260343 》 谢谢支持!★★★

在进行国际性软件项目开发的过程中,有时候会碰到一些比较特殊的要求。比如:比如说,你做的是个购物网站(假设服务器放在中国上海),当全世界客户在你的网站上下订单买东西后,往往希望看到客户所在地下单时间,比如说我是个美国纽约人,我在你的网站上下单后,你给我看到一个上海的下单时间,会觉得非常的奇怪。众所周知,纽约时间相对上海时间大约要晚13小时,如果让客户看到本地时区的时间,将变得更加符合客户的时间观念,使得客户理解比较方便。

其实,java中早已考虑过世界时区(TimeZone)这个问题,并给出了比较合理的解决方法,可以比较方便的进行世界时区时间的转化,将一个时区的时间转换成另一个时区的时间。可以看看下面的的实际例子(运行例子的main()方法)。

关于如何知道客户所在的时区,可以根据客户所在的ip或者用户注册提供的国家来计算出所在的时区。

Java代码
  1. /*  
  2.  * Created on 2005-6-10  
  3.  * Author stephen  
  4.  * Email zhoujianqiang AT gmail DOT com  
  5.  * CopyRight(C)2005-2008 , All rights reserved.  
  6.  */  
  7. package com.soft4j.utility;   
  8.   
  9. import java.text.ParseException;   
  10. import java.text.SimpleDateFormat;   
  11. import java.util.Date;   
  12. import java.util.GregorianCalendar;   
  13. import java.util.TimeZone;   
  14. import java.util.Vector;   
  15.   
  16. import com.soft4j.log.Log;   
  17.   
  18. /**  
  19.  * 与日期、时间相关的一些常用工具方法.  
  20.  * 

     

  21.  * 日期(时间)的常用格式(formater)主要有: 
     
  22.  * yyyy-MM-dd HH:mm:ss 
     
  23.  *   
  24.  * @author stephen  
  25.  * @version 1.0.0  
  26.  */  
  27. public final class DateTool {   
  28.   
  29.     /**  
  30.      * 对日期(时间)中的日进行加减计算. 
     
  31.      * 例子: 
     
  32.      * 如果Date类型的d为 2005年8月20日,那么 
     
  33.      * calculateByDate(d,-10)的值为2005年8月10日 
     
  34.      * 而calculateByDate(d,+10)的值为2005年8月30日 
     
  35.      *   
  36.      * @param d  
  37.      *            日期(时间).  
  38.      * @param amount  
  39.      *            加减计算的幅度.+n=加n天;-n=减n天.  
  40.      * @return 计算后的日期(时间).  
  41.      */  
  42.     public static Date calculateByDate(Date d, int amount) {   
  43.         return calculate(d, GregorianCalendar.DATE, amount);   
  44.     }   
  45.        
  46.     public static Date calculateByMinute(Date d, int amount) {   
  47.         return calculate(d, GregorianCalendar.MINUTE, amount);   
  48.     }   
  49.        
  50.     public static Date calculateByYear(Date d, int amount) {   
  51.         return calculate(d, GregorianCalendar.YEAR, amount);   
  52.     }   
  53.   
  54.     /**  
  55.      * 对日期(时间)中由field参数指定的日期成员进行加减计算. 
     
  56.      * 例子: 
     
  57.      * 如果Date类型的d为 2005年8月20日,那么 
     
  58.      * calculate(d,GregorianCalendar.YEAR,-10)的值为1995年8月20日 
     
  59.      * 而calculate(d,GregorianCalendar.YEAR,+10)的值为2015年8月20日 
     
  60.      *   
  61.      * @param d  
  62.      *            日期(时间).  
  63.      * @param field  
  64.      *            日期成员. 
     
  65.      *            日期成员主要有: 
     
  66.      *            年:GregorianCalendar.YEAR 
     
  67.      *            月:GregorianCalendar.MONTH 
     
  68.      *            日:GregorianCalendar.DATE 
     
  69.      *            时:GregorianCalendar.HOUR 
     
  70.      *            分:GregorianCalendar.MINUTE 
     
  71.      *            秒:GregorianCalendar.SECOND 
     
  72.      *            毫秒:GregorianCalendar.MILLISECOND 
     
  73.      * @param amount  
  74.      *            加减计算的幅度.+n=加n个由参数field指定的日期成员值;-n=减n个由参数field代表的日期成员值.  
  75.      * @return 计算后的日期(时间).  
  76.      */  
  77.     private static Date calculate(Date d, int field, int amount) {   
  78.         if (d == null)   
  79.             return null;   
  80.         GregorianCalendar g = new GregorianCalendar();   
  81.         g.setGregorianChange(d);   
  82.         g.add(field, amount);   
  83.         return g.getTime();   
  84.     }   
  85.   
  86.     /**  
  87.      * 日期(时间)转化为字符串.  
  88.      *   
  89.      * @param formater  
  90.      *            日期或时间的格式.  
  91.      * @param aDate  
  92.      *            java.util.Date类的实例.  
  93.      * @return 日期转化后的字符串.  
  94.      */  
  95.     public static String date2String(String formater, Date aDate) {   
  96.         if (formater == null || "".equals(formater))   
  97.             return null;   
  98.         if (aDate == null)   
  99.             return null;   
  100.         return (new SimpleDateFormat(formater)).format(aDate);   
  101.     }   
  102.   
  103.     /**  
  104.      * 当前日期(时间)转化为字符串.  
  105.      *   
  106.      * @param formater  
  107.      *            日期或时间的格式.  
  108.      * @return 日期转化后的字符串.  
  109.      */  
  110.     public static String date2String(String formater) {   
  111.         return date2String(formater, new Date());   
  112.     }   
  113.        
  114.     /**  
  115.      * 获取当前日期对应的星期数.  
  116.      * 
    1=星期天,2=星期一,3=星期二,4=星期三,5=星期四,6=星期五,7=星期六
     
  117.      * @return 当前日期对应的星期数  
  118.      */  
  119.     public static int dayOfWeek() {   
  120.         GregorianCalendar g = new GregorianCalendar();   
  121.         int ret = g.get(java.util.Calendar.DAY_OF_WEEK);   
  122.         g = null;   
  123.         return ret;   
  124.     }   
  125.   
  126.   
  127.     /**  
  128.      * 获取所有的时区编号. 
     
  129.      * 排序规则:按照ASCII字符的正序进行排序. 
     
  130.      * 排序时候忽略字符大小写.  
  131.      *   
  132.      * @return 所有的时区编号(时区编号已经按照字符[忽略大小写]排序).  
  133.      */  
  134.     public static String[] fecthAllTimeZoneIds() {   
  135.         Vector v = new Vector();   
  136.         String[] ids = TimeZone.getAvailableIDs();   
  137.         for (int i = 0; i < ids.length; i++) {   
  138.             v.add(ids[i]);   
  139.         }   
  140.         java.util.Collections.sort(v, String.CASE_INSENSITIVE_ORDER);   
  141.         v.copyInto(ids);   
  142.         v = null;   
  143.         return ids;   
  144.     }   
  145.   
  146.     /**  
  147.      * 测试的main方法.  
  148.      *   
  149.      * @param argc  
  150.      */  
  151.     public static void main(String[] argc) {   
  152.            
  153.         String[] ids = fecthAllTimeZoneIds();   
  154.         String nowDateTime =date2String("yyyy-MM-dd HH:mm:ss");   
  155.         System.out.println("The time Asia/Shanhai is " + nowDateTime);//程序本地运行所在时区为[Asia/Shanhai]   
  156.         //显示世界每个时区当前的实际时间   
  157.         for(int i=0;i 
  158.             System.out.println(" * " + ids[i] + "=" + string2TimezoneDefault(nowDateTime,ids[i]));    
  159.         }   
  160.         //显示程序运行所在地的时区   
  161.         System.out.println("TimeZone.getDefault().getID()=" +TimeZone.getDefault().getID());   
  162.     }   
  163.   
  164.     /**  
  165.      * 将日期时间字符串根据转换为指定时区的日期时间.  
  166.      *   
  167.      * @param srcFormater  
  168.      *            待转化的日期时间的格式.  
  169.      * @param srcDateTime  
  170.      *            待转化的日期时间.  
  171.      * @param dstFormater  
  172.      *            目标的日期时间的格式.  
  173.      * @param dstTimeZoneId  
  174.      *            目标的时区编号.  
  175.      *   
  176.      * @return 转化后的日期时间.  
  177.      */  
  178.     public static String string2Timezone(String srcFormater,   
  179.             String srcDateTime, String dstFormater, String dstTimeZoneId) {   
  180.         if (srcFormater == null || "".equals(srcFormater))   
  181.             return null;   
  182.         if (srcDateTime == null || "".equals(srcDateTime))   
  183.             return null;   
  184.         if (dstFormater == null || "".equals(dstFormater))   
  185.             return null;   
  186.         if (dstTimeZoneId == null || "".equals(dstTimeZoneId))   
  187.             return null;   
  188.         SimpleDateFormat sdf = new SimpleDateFormat(srcFormater);   
  189.         try {   
  190.             int diffTime = getDiffTimeZoneRawOffset(dstTimeZoneId);   
  191.             Date d = sdf.parse(srcDateTime);   
  192.             long nowTime = d.getTime();   
  193.             long newNowTime = nowTime - diffTime;   
  194.             d = new Date(newNowTime);   
  195.             return date2String(dstFormater, d);   
  196.         } catch (ParseException e) {   
  197.             Log.output(e.toString(), Log.STD_ERR);   
  198.             return null;   
  199.         } finally {   
  200.             sdf = null;   
  201.         }   
  202.     }   
  203.   
  204.     /**  
  205.      * 获取系统当前默认时区与UTC的时间差.(单位:毫秒)  
  206.      *   
  207.      * @return 系统当前默认时区与UTC的时间差.(单位:毫秒)  
  208.      */  
  209.     private static int getDefaultTimeZoneRawOffset() {   
  210.         return TimeZone.getDefault().getRawOffset();   
  211.     }   
  212.   
  213.     /**  
  214.      * 获取指定时区与UTC的时间差.(单位:毫秒)  
  215.      *   
  216.      * @param timeZoneId  
  217.      *            时区Id  
  218.      * @return 指定时区与UTC的时间差.(单位:毫秒)  
  219.      */  
  220.     private static int getTimeZoneRawOffset(String timeZoneId) {   
  221.         return TimeZone.getTimeZone(timeZoneId).getRawOffset();   
  222.     }   
  223.   
  224.     /**  
  225.      * 获取系统当前默认时区与指定时区的时间差.(单位:毫秒)  
  226.      *   
  227.      * @param timeZoneId  
  228.      *            时区Id  
  229.      * @return 系统当前默认时区与指定时区的时间差.(单位:毫秒)  
  230.      */  
  231.     private static int getDiffTimeZoneRawOffset(String timeZoneId) {   
  232.         return TimeZone.getDefault().getRawOffset()   
  233.                 - TimeZone.getTimeZone(timeZoneId).getRawOffset();   
  234.     }   
  235.   
  236.     /**  
  237.      * 将日期时间字符串根据转换为指定时区的日期时间.  
  238.      *   
  239.      * @param srcDateTime  
  240.      *            待转化的日期时间.  
  241.      * @param dstTimeZoneId  
  242.      *            目标的时区编号.  
  243.      *   
  244.      * @return 转化后的日期时间.  
  245.      * @see #string2Timezone(String, String, String, String)  
  246.      */  
  247.     public static String string2TimezoneDefault(String srcDateTime,   
  248.             String dstTimeZoneId) {   
  249.         return string2Timezone("yyyy-MM-dd HH:mm:ss", srcDateTime,   
  250.                 "yyyy-MM-dd HH:mm:ss", dstTimeZoneId);   
  251.     }   
  252.   
  253. }  

你可能感兴趣的:(JAVA)