java對世界各個時區(TimeZone)的通用轉換處理方法
阿新 • • 發佈:2019-01-09
在進行國際性軟體專案開發的過程中,有時候會碰到一些比較特殊的要求。比如:比如說,你做的是個購物網站(假設伺服器放在中國上海),當全世界客戶在你的網站上下訂單買東西后,往往希望看到客戶所在地下單時間,比如說我是個美國紐約人,我在你的網站上下單後,你給我看到一個上海的下單時間,會覺得非常的奇怪。眾所周知,紐約時間相對上海時間大約要晚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
- */
- publicfinalclass 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 計算後的日期(時間).
- */
- publicstatic Date calculateByDate(Date d, int amount) {
- return calculate(d, GregorianCalendar.DATE, amount);
- }
- publicstatic Date calculateByMinute(Date d, int amount) {
- return calculate(d, GregorianCalendar.MINUTE, amount);
- }
- publicstatic 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 計算後的日期(時間).
- */
- privatestatic Date calculate(Date d, int field, int amount) {
- if (d == null)
- returnnull;
- GregorianCalendar g = new GregorianCalendar();
- g.setGregorianChange(d);
- g.add(field, amount);
- return g.getTime();
- }
- /**
- * 日期(時間)轉化為字串.
- *
- * @param formater
- * 日期或時間的格式.
- * @param aDate
- * java.util.Date類的例項.
- * @return 日期轉化後的字串.
- */
- publicstatic String date2String(String formater, Date aDate) {
- if (formater == null || "".equals(formater))
- returnnull;
- if (aDate == null)
- returnnull;
- return (new SimpleDateFormat(formater)).format(aDate);
- }
- /**
- * 當前日期(時間)轉化為字串.
- *
- * @param formater
- * 日期或時間的格式.
- * @return 日期轉化後的字串.
- */
- publicstatic String date2String(String formater) {
- return date2String(formater, new Date());
- }
- /**
- * 獲取當前日期對應的星期數.
- * <br>1=星期天,2=星期一,3=星期二,4=星期三,5=星期四,6=星期五,7=星期六
- * @return 當前日期對應的星期數
- */
- publicstaticint dayOfWeek() {
- GregorianCalendar g = new GregorianCalendar();
- int ret = g.get(java.util.Calendar.DAY_OF_WEEK);
- g = null;
- return ret;
- }
- /**
- * 獲取所有的時區編號. <br>
- * 排序規則:按照ASCII字元的正序進行排序. <br>
- * 排序時候忽略字元大小寫.
- *
- * @return 所有的時區編號(時區編號已經按照字元[忽略大小寫]排序).
- */
- publicstatic 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
- */
- publicstaticvoid 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 轉化後的日期時間.
- */
- publicstatic String string2Timezone(String srcFormater,
- String srcDateTime, String dstFormater, String dstTimeZoneId) {
- if (srcFormater == null || "".equals(srcFormater))
- returnnull;
- if (srcDateTime == null || "".equals(srcDateTime))
- returnnull;
- if (dstFormater == null || "".equals(dstFormater))
- returnnull;
- if (dstTimeZoneId == null || "".equals(dstTimeZoneId))
- returnnull;
- 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);
- returnnull;
- } finally {
- sdf = null;
- }
- }
- /**
- * 獲取系統當前預設時區與UTC的時間差.(單位:毫秒)
- *
- * @return 系統當前預設時區與UTC的時間差.(單位:毫秒)
- */
- privatestaticint getDefaultTimeZoneRawOffset() {
- return TimeZone.getDefault().getRawOffset();
- }
- /**
- * 獲取指定時區與UTC的時間差.(單位:毫秒)
- *
- * @param timeZoneId
- * 時區Id
- * @return 指定時區與UTC的時間差.(單位:毫秒)
- */
- privatestaticint getTimeZoneRawOffset(String timeZoneId) {
- return TimeZone.getTimeZone(timeZoneId).getRawOffset();
- }
- /**
- * 獲取系統當前預設時區與指定時區的時間差.(單位:毫秒)
- *
- * @param timeZoneId
- * 時區Id
- * @return 系統當前預設時區與指定時區的時間差.(單位:毫秒)
- */
- privatestaticint getDiffTimeZoneRawOffset(String timeZoneId) {
- return TimeZone.getDefault().getRawOffset()
- - TimeZone.getTimeZone(timeZoneId).getRawOffset();
- }
- /**
- * 將日期時間字串根據轉換為指定時區的日期時間.
- *
- * @param srcDateTime
- * 待轉化的日期時間.
- * @param dstTimeZoneId
- * 目標的時區編號.
- *
- * @return 轉化後的日期時間.
- * @see #string2Timezone(String, String, String, String)
- */
- publicstatic String string2TimezoneDefault(String srcDateTime,
- String dstTimeZoneId) {
- return string2Timezone("yyyy-MM-dd HH:mm:ss", srcDateTime,
- "yyyy-MM-dd HH:mm:ss", dstTimeZoneId);
- }
- }