import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

public class Test
{
   
    public static void main(String[] args)
    {
        System.out.println("默认时区:" + getLocalTimeId());
        System.out.println("时区列表:" + getZoneList());
       
        //原时区的时间
        String sourceTime = "2013-08-06 15:30:00";
        //原时区东八区Asia/Shanghai,GMT+8:00
        String sourceId = "Asia/Shanghai";
        //目标时区Asia/Dili,GMT+09:00
        String targetId = "Asia/Dili";
        //转换后的时间
        String targetTime = timeConvert(sourceTime, sourceId, targetId);
        System.out.println("原来为:" + sourceTime);
        System.out.println("转换为:" + targetTime);
       
    }
   
    /**
     * 获取本地默认时区id
     * @return string 本地时区id
     */
    public static String getLocalTimeId()
    {
        TimeZone defaultTimeZone = TimeZone.getDefault();
        String sourceId = defaultTimeZone.getID();
        return sourceId;
    }
   
    /**
     * 获取受支持的所有可用 ID
     * 用来作为页面显示的时区下拉列表
     * 以绝对时区显示(不考虑夏令时)
     * @return map 存储时区列表+偏移量的map(可用来显示如Hongkong,GMT+08:00)
     * 实际使用时,传给服务器是零时区,值传递时区id就可以了,不传递偏移量
     */
    public static Map<String, String> getZoneList()
    {
        String[] zoneIds = TimeZone.getAvailableIDs();
        int length = zoneIds.length;
        TimeZone timeZone = null;
        //存储时区列表+偏移量到map中
        Map<String, String> map = new HashMap<String, String>(650);
        long offset = 0L;
        String diplayOffset = "";
        for (int i = 0; i < length; i++)
        {
            //获取给定 ID 的 TimeZone
            timeZone = TimeZone.getTimeZone(zoneIds[i]);
            //返回添加到 UTC 以获取此时区中的标准时间的时间偏移量(以毫秒为单位)。
            offset = timeZone.getRawOffset();
            //对偏移量做显示,如GMT-09:30、GMT+09:30
            diplayOffset = appendZoneSuffix(offset);
            //存储到map中,形式为Hongkong---GMT+08:00
            map.put(zoneIds[i], diplayOffset);
        }
        return map;
    }
   
    /**
     * 添加时区偏移量
     * @param offset 偏移量(以毫秒为单位)
     * @return 日期
     */
    public static String appendZoneSuffix(long offset)
    {
        //将偏移量转化为小时(小数去除不要)
        long hour = Long.valueOf((offset / 3600000));
        //偏移量对小时取余数,得到小数(以毫秒为单位)
        double decimals = offset % 3600000;
        //显示为09:30分钟形式
        double decimalsZone = (decimals / 3600000) * 60 / 100;
        String sAdd = "";
        if (hour >= 0)
        {
            sAdd = "+";
        }
        else
        {
            sAdd = "-";
        }
        hour = hour > 0 ? hour : -hour;
        String sHour = hour + "";
        if (sHour.length() == 1)
        {
            sHour = '0' + sHour;
        }
       
        decimalsZone = decimalsZone < 0 ? -decimalsZone : decimalsZone;
        String sDecimalsZone = decimalsZone + "";
        sDecimalsZone = sDecimalsZone.substring(2);
        if (sDecimalsZone.length() == 1)
        {
            sDecimalsZone = sDecimalsZone + '0';
        }
        else if (sDecimalsZone.length() >= 3)
        {
            sDecimalsZone = sDecimalsZone.substring(0, 2);
        }
        return "GMT" + sAdd + sHour + ':' + sDecimalsZone;
    }
   
    /**
     * 时区 时间转换方法:将当前时间(可能为其他时区)转化成目标时区对应的时间
     * @param sourceTime 时间格式必须为:yyyy-MM-dd HH:mm:ss
     * @param sourceId 入参的时间的时区id
     * @param targetId 要转换成目标时区id(一般是是零时区:取值UTC)
     * @return string 转化时区后的时间
     */
    public static String timeConvert(String sourceTime, String sourceId,
            String targetId)
    {
        //校验入参是否合法
        if (null == sourceId || "".equals(sourceId) || null == targetId
                || "".equals(targetId) || null == sourceTime
                || "".equals(sourceTime))
        {
            return "";
        }
        //校验 时间格式必须为:yyyy-MM-dd HH:mm:ss
        String reg = "^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$";
        if (!sourceTime.matches(reg))
        {
            return "";
        }
       
        try
        {
            //时间格式
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //根据入参原时区id,获取对应的timezone对象
            TimeZone sourceTimeZone = TimeZone.getTimeZone(sourceId);
            //设置SimpleDateFormat时区为原时区(否则是本地默认时区),目的:用来将字符串sourceTime转化成原时区对应的date对象
            df.setTimeZone(sourceTimeZone);
            //将字符串sourceTime转化成原时区对应的date对象
            Date sourceDate = df.parse(sourceTime);
           
            //开始转化时区:根据目标时区id设置目标TimeZone
            TimeZone targetTimeZone = TimeZone.getTimeZone(targetId);
            //设置SimpleDateFormat时区为目标时区(否则是本地默认时区),目的:用来将字符串sourceTime转化成目标时区对应的date对象
            df.setTimeZone(targetTimeZone);
            //得到目标时间字符串
            String targetTime = df.format(sourceDate);
            return targetTime;
        }
        catch (ParseException e)
        {
            e.printStackTrace();
        }
        return "";
       
    }
}

java时区转化相关工具方法的更多相关文章

  1. Java时区问题

    Java时区相关 时间格式 UTC是以原子时计时,更加精准,适应现代社会的精确计时.不过一般使用不需要精确到秒时,视为等同.GMT是前世界标准时,UTC是现世界标准时.每年格林尼治天文台会发调时信息, ...

  2. Java parseInt_使用此方法得到的原始数据类型的一个特定的字符串

    Java parseInt解释加方法示例     使用此方法得到的原始数据类型的一个特定的字符串. parseXxx()是一个静态方法,可以有一个参数或两个         java parseInt ...

  3. 将 Maven生成的java项目转化为支持 Eclipse IDE的项目

    转自: http://www.xuebuyuan.com/1297046.html 将 Maven生成的java项目转化为支持 Eclipse IDE的项目   在前一篇文章中,我们使用maven创建 ...

  4. 如何重写Java中的equals方法

    Java中,只有8种基本类型不是对象,例如:4种整形类型(byte, short, int,long),2种浮点类型(flout, double),boolean, char不是对象,其他的所有类型, ...

  5. java类加载机制及方法调用

    类加载机制 概述 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading).验证(Verification).准备(Preparation).解析(Resoluti ...

  6. java获取文件大小的方法

    目前Java获取文件大小的方法有两种: 1.通过file的length()方法获取: 2.通过流式方法获取: 通过流式方法又有两种,分别是旧的java.io.*中FileInputStream的ava ...

  7. 几周内搞定Java的10个方法

    不要将Java与JavaScript弄混了,Java的目标是“一次编译,到处调试”(呃,不对,是“到处运行”).简单来说,就是Java程序可以直接在任何设备上运行. Java语言是什么? 不管我们是否 ...

  8. Bean进行操作的相关工具方法

    Bean进行操作的相关工具方法 /** * <html> * <body> * <P> Copyright 1994 JsonInternational</p ...

  9. Java基本概念:方法

    一.简介 描述: Java中方法是语句的集合,它们在一起执行一个功能. 方法是解决一类问题的步骤的有序组合,它在类中定义,属于类的成员,包含于类或对象中. 方法在程序中被创建后,在其他使用了该方法的地 ...

随机推荐

  1. Apache Rewrite规则详解

    参考链接:http://slj.me/2009/04/apache-rewrite-regular/ 1.Rewrite规则简介 Rewirte主要的功能就是实现URL的跳转,它的正则表达式是基于Pe ...

  2. LintCode: Search A 2d Matrix

    1. 设查找的数位y,第一行最后一列的数位x 如果x<y,x是第一行最大的,所以第一行都小于y,删除第一行: 如果x>y,x是最后一列最小的,所以最后一列都大于y,删除最后一列: 这样保证 ...

  3. C++ 第七课 标准 C I/O

    clearerr() 清除错误 fclose() 关闭一个文件 feof() 如果到达文件尾(end-of-file)返回"True"(真) ferror() 检查一个文件错误 f ...

  4. MySql 错误代码 1045

    错误代码 1045Access denied for user 'root'@'localhost' (using password:YES)解决办法是重新设置root用户密码,在Windows平台下 ...

  5. SpringMVC学习笔记二:常用注解

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6831976.html  参考:http://www.cnblogs.com/leskang/p/5445698 ...

  6. 关于XCode更换项目名称

    1.打开项目直接修改项目名称 2.直接修改分组名 3.然后.command+B会报错 4.找到项目源文件 YourProject.xcodeproj  - > 右键显示包内容->找到pro ...

  7. dubbo应用架构演进路线图

    1.单应用单服务器: 2.单应用拆分成多个应用并部署到多个服务器: 3.单应用拆分成多个应用并实现分布式部署: 4.流动计算框架(用于提高机器利用率的资源调度和治理中心).

  8. 使用VTK与Python实现机械臂三维模型可视化

    三维可视化系统的建立依赖于三维图形平台, 如 OpenGL.VTK.OGRE.OSG等, 传统的方法多采用OpenGL进行底层编程,即对其特有的函数进行定量操作, 需要开发人员熟悉相关函数, 从而造成 ...

  9. AVERAGE和averageif函数

    1.AVERAGE(Number1,Number2……) 其中: Number1,number2,...是要计算平均值的 1-30 个参数. 注意事项: average函数的参数可以是一个,也可以是多 ...

  10. Hadoop之我见

    最近在学习Hadoop,很想把自己的一些学习遇到的问题以及解决方案分享出来,也碍于最近一堆忙不完的事,就把这事给搁了很久. 那下面我就先来简单说下我为什么要学习Hadoop以及我学习Hadoop的一些 ...