`

java时区问题

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


在进行国际性软件项目开发的过程中,有时候会碰到一些比较特殊的要求。比如:比如说,你做的是个购物网站(假设服务器放在中国上海),当全世界客户在你的网站上下订单买东西后,往往希望看到客户所在地下单时间,比如说我是个美国纽约人,我在你的网站上下单后,你给我看到一个上海的下单时间,会觉得非常的奇怪。众所周知,纽约时间相对上海时间大约要晚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.}

分享到:
评论

相关推荐

    java 时区转换工具包

    1. 获取时区时间 public static ZonedDateTime getNow(int offset) 2. 解析指定时间 public static ZonedDateTime parse(String date,String dateFormat,int offset) 3. 获取某一天的零点 public static ...

    java的时区问题

    注册表文件 博文链接:https://lrz0534.iteye.com/blog/222887

    java.util.TimeZone 的世界时区列表

    世界范围内的时区列表。由 java.util.TimeZone 类导出

    java转换时区时间过程详解

    主要介绍了java转换时区时间过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    系统时间注册表,修正JAVA Eclipise时区问题

    用户的测试机安装的win7,测试时发现时间总是差8个小时。 在win7下装JDK1.4和JDK1.5、eclipse,输出系统时区和时间。...导入本压缩包中国时区注册表.reg 解决2003 WIN7 时区问题。 再有疑问联系,CSDN:lawsystem

    基于java时区转换夏令时的问题及解决方法

    下面小编就为大家分享一篇基于java时区转换夏令时的问题及解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

    java时区转换的理解及示例详解

    主要介绍了java时区转换的理解及示例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    java国际化&时间处理

    NULL 博文链接:https://hoochiang.iteye.com/blog/1848534

    Java完成UTC与BJT时区的转换

    Java初学者练习题,使用if else循环完成,可对初学者提供一定的参考。

    Java处理时区的注意事项

    说起java中的时间,大家或许都很熟悉,朗朗上口的Date、Calendar、SimpleDateFormat等。但是大家对他们的认识真的很深刻吗?我要想大家说的是TimeZone,即时区。  经常有人发现时间不对,比如相差8个小时等等,其...

    Java时区转换实例代码解析

    主要介绍了Java时区转换实例代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Java时区转换及Date类实现原理解析

    主要介绍了Java时区转换及Date类实现原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Java时区处理之Date,Calendar,TimeZone,SimpleDateFormat的区别于用法

    主要介绍了Java时区处理之Date,Calendar,TimeZone,SimpleDateFormat的区别于用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    Java对世界不同时区timezone之间时间转换的处理方法

    主要介绍了Java对世界不同时区timezone之间时间转换的处理方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    Android 完美获取手机当前时区,解决时间偏移量和夏令时差问题

    Android 完美获取手机当前时区,解决时间偏移量和夏令时差问题.从本地时间里扣除这些变量,即可以取得UTC时间

    关于Java中的mysql时区问题详解

    主要给大家介绍了关于Java中mysql时区问题的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

Global site tag (gtag.js) - Google Analytics