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.}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值