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

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

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

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

Java代码
  01./*  02. * Created on 2005-6-10  03. * Author stephen  04. * Email zhoujianqiang AT gmail DOT com  05. * CopyRight(C)2005-2008 , All rights reserved.  06. */  07.package com.soft4j.utility;   08.  09.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. * <p>  21. * 日期(时间)的常用格式(formater)主要有: <br>  22. * yyyy-MM-dd HH:mm:ss <br>  23. *   24. * @author stephen  25. * @version 1.0.0  26. */  27.public final class DateTool {   28.  29.    /**  30.     * 对日期(时间)中的日进行加减计算. <br>  31.     * 例子: <br>  32.     * 如果Date类型的d为 2005年8月20日,那么 <br>  33.     * calculateByDate(d,-10)的值为2005年8月10日 <br>  34.     * 而calculateByDate(d,+10)的值为2005年8月30日 <br>  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参数指定的日期成员进行加减计算. <br>  56.     * 例子: <br>  57.     * 如果Date类型的d为 2005年8月20日,那么 <br>  58.     * calculate(d,GregorianCalendar.YEAR,-10)的值为1995年8月20日 <br>  59.     * 而calculate(d,GregorianCalendar.YEAR,+10)的值为2015年8月20日 <br>  60.     *   61.     * @param d  62.     *            日期(时间).  63.     * @param field  64.     *            日期成员. <br>  65.     *            日期成员主要有: <br>  66.     *            年:GregorianCalendar.YEAR <br>  67.     *            月:GregorianCalendar.MONTH <br>  68.     *            日:GregorianCalendar.DATE <br>  69.     *            时:GregorianCalendar.HOUR <br>  70.     *            分:GregorianCalendar.MINUTE <br>  71.     *            秒:GregorianCalendar.SECOND <br>  72.     *            毫秒:GregorianCalendar.MILLISECOND <br>  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.     * <br>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.     * 获取所有的时区编号. <br>  129.     * 排序规则:按照ASCII字符的正序进行排序. <br>  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 <ids.length;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.} 
原创粉丝点击