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


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

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

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

    /*
     * Created on 2005-6-10
     * Author stephen
     * Email zhoujianqiang AT gmail DOT com
     * CopyRight(C)2005-2008 , All rights reserved.
     */
    package com.soft4j.utility;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.GregorianCalendar;
    import java.util.TimeZone;
    import java.util.Vector;
    
    import com.soft4j.log.Log;
    
    /**
     * 与日期、时间相关的一些常用工具方法.
     * <p>
     * 日期(时间)的常用格式(formater)主要有: <br>
     * yyyy-MM-dd HH:mm:ss <br>
     * 
     * @author stephen
     * @version 1.0.0
     */
    public final class DateTool {
    
        /**
         * 对日期(时间)中的日进行加减计算. <br>
         * 例子: <br>
         * 如果Date类型的d为 2005年8月20日,那么 <br>
         * calculateByDate(d,-10)的值为2005年8月10日 <br>
         * 而calculateByDate(d,+10)的值为2005年8月30日 <br>
         * 
         * @param d
         *            日期(时间).
         * @param amount
         *            加减计算的幅度.+n=加n天;-n=减n天.
         * @return 计算后的日期(时间).
         */
        public static Date calculateByDate(Date d, int amount) {
            return calculate(d, GregorianCalendar.DATE, amount);
        }
        
        public static Date calculateByMinute(Date d, int amount) {
            return calculate(d, GregorianCalendar.MINUTE, amount);
        }
        
        public static Date calculateByYear(Date d, int amount) {
            return calculate(d, GregorianCalendar.YEAR, amount);
        }
    
        /**
         * 对日期(时间)中由field参数指定的日期成员进行加减计算. <br>
         * 例子: <br>
         * 如果Date类型的d为 2005年8月20日,那么 <br>
         * calculate(d,GregorianCalendar.YEAR,-10)的值为1995年8月20日 <br>
         * 而calculate(d,GregorianCalendar.YEAR,+10)的值为2015年8月20日 <br>
         * 
         * @param d
         *            日期(时间).
         * @param field
         *            日期成员. <br>
         *            日期成员主要有: <br>
         *            年:GregorianCalendar.YEAR <br>
         *            月:GregorianCalendar.MONTH <br>
         *            日:GregorianCalendar.DATE <br>
         *            时:GregorianCalendar.HOUR <br>
         *            分:GregorianCalendar.MINUTE <br>
         *            秒:GregorianCalendar.SECOND <br>
         *            毫秒:GregorianCalendar.MILLISECOND <br>
         * @param amount
         *            加减计算的幅度.+n=加n个由参数field指定的日期成员值;-n=减n个由参数field代表的日期成员值.
         * @return 计算后的日期(时间).
         */
        private static Date calculate(Date d, int field, int amount) {
            if (d == null)
                return null;
            GregorianCalendar g = new GregorianCalendar();
            g.setGregorianChange(d);
            g.add(field, amount);
            return g.getTime();
        }
    
        /**
         * 日期(时间)转化为字符串.
         * 
         * @param formater
         *            日期或时间的格式.
         * @param aDate
         *            java.util.Date类的实例.
         * @return 日期转化后的字符串.
         */
        public static String date2String(String formater, Date aDate) {
            if (formater == null || "".equals(formater))
                return null;
            if (aDate == null)
                return null;
            return (new SimpleDateFormat(formater)).format(aDate);
        }
    
        /**
         * 当前日期(时间)转化为字符串.
         * 
         * @param formater
         *            日期或时间的格式.
         * @return 日期转化后的字符串.
         */
        public static String date2String(String formater) {
            return date2String(formater, new Date());
        }
        
        /**
         * 获取当前日期对应的星期数.
         * <br>1=星期天,2=星期一,3=星期二,4=星期三,5=星期四,6=星期五,7=星期六
         * @return 当前日期对应的星期数
         */
        public static int dayOfWeek() {
            GregorianCalendar g = new GregorianCalendar();
            int ret = g.get(java.util.Calendar.DAY_OF_WEEK);
            g = null;
            return ret;
        }
    
    
        /**
         * 获取所有的时区编号. <br>
         * 排序规则:按照ASCII字符的正序进行排序. <br>
         * 排序时候忽略字符大小写.
         * 
         * @return 所有的时区编号(时区编号已经按照字符[忽略大小写]排序).
         */
        public static String[] fecthAllTimeZoneIds() {
            Vector v = new Vector();
            String[] ids = TimeZone.getAvailableIDs();
            for (int i = 0; i < ids.length; i++) {
                v.add(ids[i]);
            }
            java.util.Collections.sort(v, String.CASE_INSENSITIVE_ORDER);
            v.copyInto(ids);
            v = null;
            return ids;
        }
    
        /**
         * 测试的main方法.
         * 
         * @param argc
         */
        public static void main(String[] argc) {
            
            String[] ids = fecthAllTimeZoneIds();
            String nowDateTime =date2String("yyyy-MM-dd HH:mm:ss");
            System.out.println("The time Asia/Shanhai is " + nowDateTime);//程序本地运行所在时区为[Asia/Shanhai]
            //显示世界每个时区当前的实际时间
            for(int i=0;i <ids.length;i++){
                System.out.println(" * " + ids[i] + "=" + string2TimezoneDefault(nowDateTime,ids[i])); 
            }
            //显示程序运行所在地的时区
            System.out.println("TimeZone.getDefault().getID()=" +TimeZone.getDefault().getID());
        }
    
        /**
         * 将日期时间字符串根据转换为指定时区的日期时间.
         * 
         * @param srcFormater
         *            待转化的日期时间的格式.
         * @param srcDateTime
         *            待转化的日期时间.
         * @param dstFormater
         *            目标的日期时间的格式.
         * @param dstTimeZoneId
         *            目标的时区编号.
         * 
         * @return 转化后的日期时间.
         */
        public static String string2Timezone(String srcFormater,
                String srcDateTime, String dstFormater, String dstTimeZoneId) {
            if (srcFormater == null || "".equals(srcFormater))
                return null;
            if (srcDateTime == null || "".equals(srcDateTime))
                return null;
            if (dstFormater == null || "".equals(dstFormater))
                return null;
            if (dstTimeZoneId == null || "".equals(dstTimeZoneId))
                return null;
            SimpleDateFormat sdf = new SimpleDateFormat(srcFormater);
            try {
                int diffTime = getDiffTimeZoneRawOffset(dstTimeZoneId);
                Date d = sdf.parse(srcDateTime);
                long nowTime = d.getTime();
                long newNowTime = nowTime - diffTime;
                d = new Date(newNowTime);
                return date2String(dstFormater, d);
            } catch (ParseException e) {
                Log.output(e.toString(), Log.STD_ERR);
                return null;
            } finally {
                sdf = null;
            }
        }
    
        /**
         * 获取系统当前默认时区与UTC的时间差.(单位:毫秒)
         * 
         * @return 系统当前默认时区与UTC的时间差.(单位:毫秒)
         */
        private static int getDefaultTimeZoneRawOffset() {
            return TimeZone.getDefault().getRawOffset();
        }
    
        /**
         * 获取指定时区与UTC的时间差.(单位:毫秒)
         * 
         * @param timeZoneId
         *            时区Id
         * @return 指定时区与UTC的时间差.(单位:毫秒)
         */
        private static int getTimeZoneRawOffset(String timeZoneId) {
            return TimeZone.getTimeZone(timeZoneId).getRawOffset();
        }
    
        /**
         * 获取系统当前默认时区与指定时区的时间差.(单位:毫秒)
         * 
         * @param timeZoneId
         *            时区Id
         * @return 系统当前默认时区与指定时区的时间差.(单位:毫秒)
         */
        private static int getDiffTimeZoneRawOffset(String timeZoneId) {
            return TimeZone.getDefault().getRawOffset()
                    - TimeZone.getTimeZone(timeZoneId).getRawOffset();
        }
    
        /**
         * 将日期时间字符串根据转换为指定时区的日期时间.
         * 
         * @param srcDateTime
         *            待转化的日期时间.
         * @param dstTimeZoneId
         *            目标的时区编号.
         * 
         * @return 转化后的日期时间.
         * @see #string2Timezone(String, String, String, String)
         */
        public static String string2TimezoneDefault(String srcDateTime,
                String dstTimeZoneId) {
            return string2Timezone("yyyy-MM-dd HH:mm:ss", srcDateTime,
                    "yyyy-MM-dd HH:mm:ss", dstTimeZoneId);
        }
    
    }

    本文转自:http://stephen830.iteye.com/blog/260343

  • 相关阅读:
    c#代码:使用假设的方法遍历解决“谁养鱼”问题(据说是爱因斯坦所出的一道推理题) 无为而为
    远洋地暖的使用步骤
    合伙人四大原则
    model y搭载60度磷酸铁锂电池的续航表现
    model3家用充电桩按220V还是380V区别?
    食用油的挑选标准
    职责链模式(Chain of Responsibility)
    通用数据链接(UDL)的用法
    Oracle REGEXP_INSTR 用法
    访问者模式(Visitor)
  • 原文地址:https://www.cnblogs.com/dreammyle/p/4271109.html
Copyright © 2020-2023  润新知